Swagger: query params on POST methods not allowed? - swagger

I've got a POST endpoint described in Swagger and I want that endpoint to also have query parameters. We're using 1.2 swagger format because, well, legacy reasons. We use 3scale, it hosts the documents and you edit your swagger in their web UI. However, when I try to save the document it gives me the following error.
JSON Spec can not have paramType='body' and paramType='query' on the same method
I can't find anything in the swagger specs that says this is an actual limitation. Is this likely something specific to 3Scale or is this a general swagger limitation? And if the latter, can someone point me at a spec is that clarifies it?
The actual REST endpoint doesn't care, it's happy with query params on a POST. It's just getting the Swagger tool to be happy. Here's the abbreviated snippet of the swagger doc:
{
"parameters": [
{
"name": "myQueryParam",
"dataType": "string",
"paramType": "query",
"required": true
},
{
"name": "body",
"dataType": "string",
"paramType": "body",
"required": true
}
],
"httpMethod": "POST"
}

not sure if the error message is a generic validation error, but there a couple of error in the specification you shared:
it is "method" and not "httpMethod"
it is "type" and not "dataType"
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/1.2.md

The following example works for me, but I use required=false:
{
"in": "query",
"name": "myQueryParam",
"required": false,
"type": "string"
}
See also Swagger parameters in query and/or body

Related

System for data validation and class generation (Avro vs Json Schema vs OpenAPI)

We want to have a system that allows us to define data schemas that we can use to validate our data, and to generate code in specific languages. We found json schema's that lets us do something like
File "message.json.schema"
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "Message",
"properties": {
"name": {
"type" : "string"
},
"type": {
"$ref": "type/message_type.schema.json"
},
"message_id":{
"$ref": "type/uuid.schema.json"
}
},
"required": ["name", "message_id"]
}
File "message_type.json.schema"
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "MessageType",
"enum": ["Message", "Query"]
}
File "uuid_type.json.schema"
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "UUID",
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
}
File "query.json.schema"
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "Query",
"allOf" : [ {"$ref": "type/message.schema.json" }],
"required": ["type"]
}
Please ignore if there is something that doesn't make sense but the point is, we really enjoy this system because it allows us to define types, and to refer to types that we create in another files, and even to use them like for type inheritance.
Then we want to use this files for code generation and validation. In python we then use a library called python_jsonschema_objects that can parse this files and the files that it references recursively, and we can then really simply create a python object with all the validation included.
But then we also want to use them for Java/Kotlin but the library that we found jsonschema2pojo doesn't seem able to parse linked files expecting everything to be in the same file.
This leads us to think that for some reason Json Schema is not that supported or used, unfortunately.
So, we have the question if a system like Avro or OpenAPI would be better supported and more widely used and could be chosen to this type of task.

Google Cloud Endpoints REST Discovery Document missing format

I've upgraded to Cloud Endpoints 2.0 which no longer supports RPC. Therefore, I generated a new discovery document and used the service generator with the REST discovery doc as input in order to generate the client library for my iOS app.
Using the new REST discovery doc I am getting the following error when trying to generate the library:
~/workspace/google-api-objectivec-client-for-rest/Source/Tools/ServiceGenerator/build/Release/ServiceGenerator discovery/servUsApi-v1-rest.discovery --outputDir GTLAPI --gtlrFrameworkName GoogleAPIClientForREST
ERROR: Failure, exception: Looking at parameter 'creditKickbackKash:creditAmount', found a type/format pair of 'number/(null)', and don't how to map that to Objective-C
I was able to manually fix this by adding (in numerous places) in the discovery doc, the "format": "double" key and value for all double parameters. Notice creditAmount below is missing a format, like all other doubles.
The generated discovery doc looks like this:
"creditKickbackKash": {
"httpMethod": "PUT",
"id": "servUsApi.admin.creditKickbackKash",
"parameterOrder": [
"userId",
"creditAmount"
],
"parameters": {
"userId": {
"format": "int64",
"location": "path",
"required": true,
"type": "string"
},
"creditAmount": {
"location": "path",
"required": true,
"type": "number"
}
},
"path": "creditKickbackKash/{userId}/{creditAmount}",
"response": {
"$ref": "ResultDTO"
},
"scopes": [
"https://www.googleapis.com/auth/userinfo.email"
]
}
Is anyone else having this issue? How can I get the discovery document generation to properly format the document including double number types?
I had the same problem. I rolled back from 1.9.50 to 1.9.48 and the problem is gone.

Dart Services API: how to access the /fixes through the API service?

I am looking at:
https://github.com/dart-lang/dart-services
And am trying to adapt the example given (https://dartpad.dartlang.org/2a7fd9328e0a567ee79b) to pull back information from '/api/dartservices/v1/fixes' rather than '/api/dartservices/v1/analyze'.
Apologies, if I am missing something obvious here but changing the path in the example to:
"https://dart-services.appspot.com/api/dartservices/v1/fixes";
returns an error. Does anyone know how I can get the information from '/api/dartservices/v1/fixes rather than '/api/dartservices/v1/analyze'? Or does anyone have an example of this working?
Thanks.
Sending a POST request to https://dart-services.appspot.com/api/dartservices/v1/fixes with the data the DartPad example sends yields the error message "Missing parameter: 'offset'".
Looking at the discovery doc for the service https://dart-services.appspot.com/api/discovery/v1/apis/dartservices/v1/rest I see both analyze and fixes operations take a SourceRequest:
"SourceRequest": {
"id": "SourceRequest",
"type": "object",
"properties": {
"source": {
"type": "string",
"description": "The Dart source.",
"required": true
},
"offset": {
"type": "integer",
"description": "An optional offset into the source code.",
"format": "int32"
},
"strongMode": {
"type": "boolean",
"description": "An optional signal whether the source should be processed in strong mode"
}
}
offset is not marked as required so maybe there is a bug in the implementation of fixes wrt that parameter.
To make the DartPad example work, change:
Map m = {'source': textArea.value};
to
Map m = {'source': textArea.value, 'offset': 0};

Nested query parameters in Swagger 2.0

I'm documenting a Rails app with Swagger 2.0 and using Swagger-UI as the human-readable documentation/sandbox solution.
I have a resource where clients can store arbitrary metadata to query later. According to the Rails convention, the query would be submitted like so:
/posts?metadata[thing1]=abc&metadata[thing2]=def
which Rails translates to params of:
{ "metadata" => { "thing1" => "abc", "thing2" => "def" } }
which can easily be used to generate the appropriate WHERE clause for the database.
Is there any support for something like this in Swagger? I want to ultimately have Swagger-UI give some way to modify the generated request to add on arbitrary params under the metadata namespace.
This doesn't appear supported yet (over 2 years after you asked the question), but there's an ongoing discussion & open ticket about adding support for this on the OpenAPI github repo. They refer to this type of nesting as deepObjects.
There's another open issue where an implementation was attempted here. Using the most recent stable swagger-ui release, however, I have observed it working as I expect:
"parameters": [
{
"name": "page[number]",
"in": "query",
"type": "integer",
"default": 1,
"required": false
},
{
"name": "page[size]",
"in": "query",
"type": "integer",
"default": 25,
"required": false
}
This presents the expected dialog box & works with Try it out against a working server.
I don't believe there is a good way to specify arbitrary or a selection of values (e.g. an enum), so you may have to add parameters for every nesting option.

How to pass empty value to a query param in swagger?

I am trying to access an url similar to http://example.com/service1?q1=a&q2=b. However q1 will not have any values associated with it sometimes but is required to access the service (http://example.com/service1?q1=&q2=b). How do I achieve this through swagger ui JSON. I've tried using allowEmptyValue option but it doesn't seem to work.
Please find below the sample JSON I tried using allowEmptyValue option,
{
"path": "/service1.do",
"operations": [{
"method": "GET",
"type": "void",
"parameters": [{
"name": "q1",
"in" : "query",
"required": false,
"type": "string",
"paramType": "query",
"allowEmptyValue": true
},{
"name": "q2",
"in" : "query",
"required": true,
"type": "string",
"paramType": "query",
}
],
"responseMessages": [{
"code": 200,
"responseModel": "/successResponseModel"
}
}
When an empty value is passed to q1, swagger frames the URL as http://example.com/service1?q2=b. Is there anyway to include q1 with empty values to be included in the URL (http://example.com/service1?q1=&q2=b) ?
Any help would be greatly appreciated.
It looks like your problem is a known issue of swagger-ui that hasn't fixed yet. see.
As a workaround you may do one of the followings.
Option 1: Specify a default value.
This option have nothing to do with swagger-ui. In your ws-implementation, You have to add a default value(in your case "") to use when 'q1' is not added. Any REST framework has this option.
As the ws-implementation perspectives, this should be there in your ws, unless you have another service to be triggered when 'q1' is not added. (which might not be a good design in most cases) And you can use this as a forever solution, not temporary.
Option 2: using enums (not a consistent solution)
As Explained in this. You can specify your query parameter 'q1' as follows for your swagger definition.
{
"in": "query",
"name": "q1",
"type": "boolean",
"required": false,
"enum" : [true],
"allowEmptyValue" : true
}
(1) "required" must be false.
(2) "allowEmptyValue" must be true.
(3) "enum" must have exactly one non-empty value.
(4) "type" must be "boolean". (or "string" with a special enum, say "INCLUDE")
I managed to solve this by setting:
"required": true,
"allowEmptyValue": true
In the Swagger-UI a checkbox will then be displayed where you can send the empty value. That worked for me. If that was checked and an empty query parameter was passed, the URL would look something like this: https://example.com?

Resources