Object as query string param in API on Open API Specification Swagger - swagger

I have an API which is accepting query param as Object. I am using this to add multiple filters to filter the result.
When I hit the request from swagger, I am getting null for my filter object in the controller.
userFilter is the POJO class. It is used as a query param and in the controller, it is coming as null.
On swagger, it is showing as below
userFilter object is not getting constructed and getting NullPointerException in controller class when trying to access any field from userFilter.

I got the solution from swagger.io.
As per the explanation, content is used in complex serialization scenarios that are not covered by style and explode. For example, if we need to send a JSON string in the query string like so:
filter={"type":"t-shirt","color":"blue"}
In this case, we need to wrap the parameter schema into content/<media-type> as shown below.
We need to add content = {#Content(schema = #Schema(type = "object"))} to the #Parameter.
#Parameter(description = "Filters", required = true, content = {#Content(schema = #Schema(type = "object"))})
In JSON format it will look like below.
parameters:
- in: query
name: filter
# Wrap 'schema' into 'content.<media-type>'
content:
application/json: # <---- media type indicates how to serialize / deserialize the parameter content
schema:
type: object
properties:
type:
type: string
color:
type: string

Related

Nestjs swagger array of strings with one parameter

When I send only one parameter, I got query result like string, not like string[]. This heppend only from UI swagger, if I send from Postman - it works good.
I just want send from swagger-ui one parammeter and got array of string, not string
How I can fix it? Help me please.
Example1: send one paramenter and in my controller I got string like '25'
Example2: when I send 2 parameters in controller I can see array of strings ('25', '21')
export class List {
#ApiProperty({ isArray: true, type: String, required: false })
#IsOptional()
public categories?: string[];
}
You should try to spread your parameter in a const in services
edit:
I don't know how to explain in formal words, but a array of strings of one item, for JAVASCRIPT, seems with the same thing as one string value.
Because array is not a type, but a form of a type....
So, if you, in your controller, before do anything with it, you redeclare as:
#Get(":id")
findManybyId(#Param("id") id: string[]) {
const idArray = [...id];
return await this.service.findManyById(idArray);
}
It will solve your problem about being an array
old answer:
You should try to change in your controller where you make your input decorator.
in your case, i don't know if you are using ID to get, but you must to do as the example:
#ApiOperation({
summary: "Get many categories by ID",
})
async getMany(
#Param("id") ids: string[],
) {
return await this.categoriesService.getMany(id);
}
when you fill a single category the query param will be translated as a string while when you fill in several categories understand it as a array.
to solve this problem I added in DTO :
#Transform(({ value }) => (Array.isArray(value) ? value : Array(value)))
I force the cast to array

Swagger client, adding a fixed parameter to the request

I am looking for a way to add a fixed parameter to every request the client sends to the server.
For example: param1=false. The default value for the server is param1=true, but I want the generated client to send false with every request. Is this somehow possible?
I have tried:
default: false - which is documented to not work for this case
defaultValue: false - which seems to only work for the UI
enum: -false - which also seems to only work for the UI
Edit
When I generate Java Code with
- name: param1
in: query
type: boolean
required: true
enum: [true]
The generated code looks like this:
private com.squareup.okhttp.Call routeGetCall(Boolean param1){
Object localVarPostBody = null;
// verify the required parameter 'param1' is set
if (param1 == null) {
throw new ApiException("Missing the required parameter 'param1' when calling routeGet(Async)");
}
... more code ...
Param1 is never forced to be true. I can even set it false. Therefore, enum seems to be only working for the UI?
While it's possible to have a constant parameter with just one possible value, such as ?param1=true:
parameters:
- name: param1
in: query
type: boolean
required: true
enum: [true]
if a parameter has multiple possible values, such as true / false (as in your example), the spec cannot force any specific value for the parameter. It's up to the client to decide which value to use.
That is, the generated client code needs to be modified to use a specific parameter value.

OData : Why am I getting HTTP 428 (Precondition Required) error while performing an update

So here's my code
sap.ui.getCore().getModel("myModel").update("/ZSystemNameSet(mandt='001')", data, null, function(datay, responsey){
sap.ui.getCore().getModel().refresh();
MessageToast.show("It worked...!! Data: "+datay+"Response: "+responsey);
}, function(datax,responsex){
MessageToast.show("Sorry! Data: "+datax+"Response: "+responsex);
});
Also how do I add the header attributes to the update() call?
Obviously your service uses optimistic locking and expects an If-Match header, containing the ETag of the entity, in the request. You can pass this ETag as parameter to the update method. For further details you should check your service definition and the documentation.
Regarding the update of header attributes: It is hard do answer as there is no information regarding your entity orchestration. Normally you should be able to add a property containing the update information for you header to the data structure you send to the server, e.g. if the header is reachable from your entity ZSystemName via association "Header" you do the following:
data.Header = { "attribute1" : value1, "attribute2" : value2 }

Breeze.js Passthrough Predicate Odata Url

I am attempting to create an odata url with multiple breeze.js passthrough predicates using documentation from the folowing link: http://www.getbreezenow.com/documentation/query-using-json.
However the generated url looks nothing like an odata url eg:
var query = breeze.EntityQuery.from('User').using(this.manager).where("{ { 'userName': { '=': '123456' } } }");
var url = query._toUri(this.manager);
url is "User?$filter=%7B%20%7B%20'userName'%3A%20%7B%20'%3D'%3A%20'123456'%20%7D%20%7D%20%7D&$orderby=UserName" rather than "User?$filter=(UserName eq '123456')&$orderby=UserName".
I don't think you want a passthru query because this just passes your where clause thru intact without any processing. This is what happens when you quote the entire where clause.
If you want your query converted to 'odata' syntax then try the following:
var query = breeze.EntityQuery.from('Customers').using(em)
.where({ 'userName': { '==': '123456' } });
Note that the 'where' argument is NOT in quotes ( it is a standard javascript object), and the operator is '==', not '=';
or even simpler
var query = breeze.EntityQuery.from('Customers').using(em)
.where( { userName: '123456' });
Further info:
There are two forms of urls that can be generated from any breeze query. An OData form and a JSON form. If you want OData, (the default) then you either do nothing because it is the default or you can tell breeze explicitly with:
breeze.core.config.initializeAdapterInstance("uriBuilder", "odata");
If you want the json form, you would use
breeze.core.config.initializeAdapterInstance("uriBuilder", "json");
It also possible that you added a line to use the 'json' uriBuilder. Just omit this line if you want OData urls. You can still construct the query via the json syntax, but the URL will be output using OData syntax.
The Json form ( or uri) is useful for non OData servers.

Facebook doesn't accept custom Open Graph properties

I'm trying to use Facebook iOS SDK 3.5 for publishing an Open Graph action. My action is:
take a photo, and photo has an additional required string property named filter.
I am creating my graph object (all values are valid and working):
NSMutableDictionary<FBOpenGraphObject> *object =
[FBGraphObject openGraphObjectForPostWithType:#"tonerapp:photo"
title:#"photo"
image:imageData
url:nil
description:title];
Then I add my filter:
object[#"tonerapp:filter"] = filterName;
I try to post the object, and I can confirm that my filter property is there (enabled FBSetting logging behavior for URL requests to show request data):
Body (w/o attachments):
object: {"description":"","type":"tonerapp:photo",
"tonerapp:filter":"classic","data":{},
"fbsdk:create_object":true,
"image":{"url":"fbstaging:\/\/graph.facebook.com\/staging_resources\/MDExMDE1MjkzNzU1Njc3MDE0MjoxNTM4NzgwNjUy","user_generated":"true"},
"title":"photo"}
I can see my filter property there, but the response is this:
error = {
code = 100;
message = "(#100) Object Missing a Required Value:
Object at URL '' of type 'tonerapp:photo' is invalid because
a required property 'tonerapp:filter' of type 'string' was not provided.";
type = OAuthException;
};
Well, it IS there. I tried all possible combinations such as:
object[#"data"] = #{#"tonerapp:filter": filterName}; //wrapping into the data object
object[#"data"] = #{#"filter": filterName}; //wrapping into data and removing namespace
object[#"toner:filter"] = filterName; //app name instead of namespace name
object[#"filter"] = filterName; //no namespace name at all
[object setObject:filterName forKey:#"tonerapp:filter"]; //setobject notation
[object setValue:filterName forKey:#"tonerapp:filter"]; //setvalue notation
[object setObject:filterName forKey:#"filter"]; //setobject AND without namespace...
and possibly more. I've tried everything, but the API always fails with the same error. I can verify the rest of the object is correct, if I go to my app in Facebook and set filter as optional instead of required, it posts successfully. Is it a bug/insufficient documentation with the Graph API, or am I so blind that I can't see something obvious here?
Thanks,
Can.
just put them under "data"
object[#"data"][#"youcustomproperty"] = #"smth";
Be sure your filterName is URL encoded. I had the same kind of issue with the name of a movie which was also a custom action on the graph. Try just to post a manual value only a simple string and let us know.

Resources