My swagger index DSL is responding with the api/v1/users.json generated from rake swagger:docs.
Api::V1::UsersController:
swagger_api :index do
summary 'Returns list of users'
notes '/api/v1/users'
end
def index
#users = User.all
render(json: { users: ActiveModel::ArraySerializer.new(#users, each_serializer: Api::V1::UserSerializer) })
end
And when I try go the the actual api documentation and run /api/v1/users.json call ("Try it out!"), I get the public api definition for the whole users api controller:
{
"apiVersion": "1.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:3000",
"resourcePath": "users",
"apis": [
{
"path": "/api/v1/users.json",
"operations": [
{
"summary": "Returns list of users",
"notes": "/api/v1/users",
"nickname": "Api::V1::Users#index",
"method": "get"
}
]
},
{
"path": "/api/v1/users/{id}.json",
"operations": [
{
"summary": "Returns a user",
"notes": "/api/v1/users/:id",
"parameters": [
{
"paramType": "path",
"name": "id",
"type": "integer",
"description": "User Id",
"required": false
}
],
"nickname": "Api::V1::Users#show",
"method": "get"
}
]
}
],
"authorizations": null
}
Also, when I try the call in Postman, it returns an array of Users like I would expect.
Related
I'm having difficulty accessing data in a collection, via PowerApps.
I create the collection with this:
Collect(coll15,mt.GetAnswers("3b....da","application/json",{question:"eco"}))
Using Developer Tools -> Network tab -> Response body - the following JSON data is returned:
{
"answers": [
{
"answer": "This is the answer",
"questions": [
"Private vehicle eco renewal"
],
"score": 82.901087775826454
}
]
}
The collection is created.
I then add a gallery control to my page - however the only options I have to bind to the labels are: ThisItem.Value
If I try to enter ThisItem.Value.answer I get the error: Invalid use of '.'
If I enter ThisItem.answers.answer I get the error: Invalid name
This is the swagger file:
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "mt",
"description": "mt"
},
"host": "westus.api.cognitive.microsoft.com:443",
"basePath": "/",
"schemes": [
"https"
],
"consumes": [],
"produces": [
"application/json"
],
"paths": {
"/qnamaker/v2.0/knowledgebases/eeeee.....eeeee/generateAnswer": {
"post": {
"summary": "GetAnswers",
"description": "Get answers from qna",
"operationId": "GetAnswers",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"type": "object",
"properties": {
"question": {
"type": "string",
"description": "question",
"x-ms-summary": "question",
"title": "question",
"x-ms-visibility": ""
}
},
"default": {
"question": "hi"
},
"required": [
"question"
]
},
"required": true
}
],
"responses": {
"default": {
"description": "default",
"schema": {
"type": "string"
}
}
}
}
}
},
"definitions": {},
"parameters": {},
"responses": {},
"securityDefinitions": {
"api_key": {
"type": "apiKey",
"in": "header",
"name": "Ocp-Apim-Subscription-Key"
}
},
"security": [
{
"oauth2_auth": [
"Offline-Access"
]
}
],
"tags": []
}
Is there any way for me to access the answer text within the collection?
Thanks for any help,
Mark
The problem is that the response type for the operation in the connector definition is string:
"responses": {
"default": {
"description": "default",
"schema": {
"type": "string"
}
}
}
But your response is an object instead. If you update your custom connector to use a typed object instead, you should be able to access the response from the operation. Something along the lines of the schema below:
"responses": {
"default": {
"description": "default",
"schema": {
"type": "object",
"properties": {
"answers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"answer": {
"type": "string"
},
"questions": {
"type": "array",
"items": {
"type": "string"
}
},
"score": {
"type": "number",
"format": "float"
}
}
}
}
}
}
}
},
Notice that in the portal (web.powerapps.com), if you go to your custom connector definition, and select "Edit", you can go to the operation, and select the response you want to edit:
And then use the "Import from sample" option
With that, if you enter an example of a response from the API, it will create the schema for you (which is similar to the one I have above).
I was wondering if anyone's done this before where they generate API docs using Swagger UI for an API not also generated by Swagger. Here's what a simple example of mine looks like:
class Api::V1::UsersController < Api::V1::BaseController
swagger_controller :users, 'Users'
swagger_api :show do
summary 'Returns a user'
param :path, :id, :integer, :optional, "User Id"
notes '/api/v1/users/:id'
response :ok, "Success", :Users
response :unauthorized
response :not_acceptable
response :not_found
end
def show
user = User.find(params[:id])
render(json: Api::V1::UserSerializer.new(user).to_json)
end
end
I've generated the swagger docs with rake swagger:docs and can reach http://localhost:3000/api-docs.json just fine where I see the documentation for Users#show, but when I click "Try it out!", I get a missing template error for api/v1/users/show
api-docs.json:
{
"apiVersion": "1.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:3000",
"apis": [
{
"path": "/api/v1/users.{format}",
"description": "Users"
}
],
"authorizations": null
}
users.json:
{
"apiVersion": "1.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:3000",
"resourcePath": "users",
"apis": [
{
"path": "/api/v1/users/{id}.json",
"operations": [
{
"summary": "Returns a user",
"parameters": [
{
"paramType": "path",
"name": "id",
"type": "integer",
"description": "User Id",
"required": false
}
],
"notes": "/api/v1/users/:id",
"responseMessages": [
{
"code": 200,
"responseModel": "Users",
"message": "Success"
},
{
"code": 401,
"responseModel": null,
"message": "Unauthorized"
},
{
"code": 404,
"responseModel": null,
"message": "Not Found"
},
{
"code": 406,
"responseModel": null,
"message": "Not Acceptable"
}
],
"nickname": "Api::V1::Users#show",
"method": "get"
}
]
}
],
"authorizations": null
}
How can I render the correct response for my show method so that it looks for the serialized json rather than a view file?
So, I found the answer. First, delete all the json files created by rake swagger:docs and add into the swagger_docs.rb initializer the following: :clean_directory => true so that everytime rake swagger:docs is run, the directory in public folder is cleared.
In order for swagger docs to work with how I'm building my API with ActiveModel's Serializers is to change up the DSL written in Api::V1::UsersController, like so:
swagger_api :show do
summary 'Returns a user'
param :path, :id, :integer, :optional, "User Id"
notes '/api/v1/users/:id'
end
then run rake swagger:docs and the call to show a user should work fine.
I have tried changing the basePath in my json file, which only seems to change the bottom "baseurl" of swagger-UI. I want to get rid of the "Default" that appears as a group title of my swagger-UI. Has anyone been able to fix this problem? I am using Swagger ~2.0.
The Default is not a path, it's a tag.
In Swagger 2.0, grouping is done using tags. Each operation can be assigned to zero or more tags. In the UI, any operation that has no tag will end up under the Default group.
"/pet/findByStatus": {
"get": {
"tags": [
"pet"
],
"summary": "Finds Pets by status",
"description": "Multiple status values can be provided with comma seperated strings",
"operationId": "findPetsByStatus",
"consumes": [
"application/xml",
"application/json",
"multipart/form-data",
"application/x-www-form-urlencoded"
],
"produces": [
"application/xml",
"application/json"
],
"parameters": [
{
"name": "status",
"in": "query",
"description": "Status values that need to be considered for filter",
"required": false,
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi",
"default": "available",
"enum": [
"available",
"pending",
"sold"
]
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
}
},
"400": {
"description": "Invalid status value"
}
},
"security": [
{
"petstore_auth": [
"write:pets",
"read:pets"
]
}
]
}
}
You can see the operations has a tags property with the value of "pet", and that operation would be grouped under that header.
I am documenting the API's of my ROR application using Swagger. This is my initializer file:
class Swagger::Docs::Config
def self.transform_path(path, api_version)
# Make a distinction between the APIs and API documentation paths.
"/apidocs/#{path}"
end
end
Swagger::Docs::Config.register_apis({
'1.0' => {
controller_base_path: '',
api_file_path: 'public/apidocs',
base_path: 'http://localhost:3000',
clean_directory: true
}})
when i run the rake task,the api-docs.json wil generate for swagger GUI.
{
"apiVersion": "1.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:3000/",
"apis": [
{
"path": "/apidocs/api/v1/users.{format}",
"description": "UserS"
}]}
But the respective JSON generated for users.json,the path is not coming out correctly.
{
"apiVersion": "1.0",
"swaggerVersion": "1.2",
"basePath": "http://localhost:3000/",
"resourcePath": "users",
"apis": [
{
"path": "api/v1/users",
"operations": [
{
"summary": "Fetches all User items",
"notes": "This lists all the active users",
"parameters": [
{.....} ]}]}]}
Instead of "path": "api/v1/users", I need to get "path": "/api/v1/users",
Inside the Swagger API Documentation there is inside the json beside the apis array a model object entry but no documentation about it. How can I use this "models" part?
{
apiVersion: "0.2",
swaggerVersion: "1.1",
basePath: "http://petstore.swagger.wordnik.com/api",
resourcePath: "/pet.{format}"
...
apis: [...]
models: {...}
}
Models are nothing but like your POJO classes in java which have variables and properties. In models section you can define your own custom class and you can refer it as data type.
If you see below
{
"path": "/pet.{format}",
"description": "Operations about pets",
"operations": [
{
"httpMethod": "POST",
"summary": "Add a new pet to the store",
"responseClass": "void",
"nickname": "addPet",
"parameters": [
{
"description": "Pet object that needs to be added to the store",
"paramType": "body",
"required": true,
"allowMultiple": false,
"dataType": "Pet"
}
],
"errorResponses": [
{
"code": 405,
"reason": "Invalid input"
}
]
}
Here in parameter section it have one parameter who's dataType is Pet and pet is defined in models as below
{
"models": {
"Pet": {
"id": "Pet",
"properties": {
"id": {
"type": "long"
},
"status": {
"allowableValues": {
"valueType": "LIST",
"values": [
"available",
"pending",
"sold"
]
},
"description": "pet status in the store",
"type": "string"
},
"name": {
"type": "string"
},
"photoUrls": {
"items": {
"type": "string"
},
"type": "Array"
}
}
}
}}
You can have nested models , for more information see Swagger PetStore example
So models are nothing but like classes.