Documenting multiple response possibilities with OpenApi annotation - swagger

I have an endpoint that can return either a single item or a list of items, depending on the parameters passed in (There's no flexibility in the endpoint currently, I am unable to make code changes).
I am trying to generate API documentation with OpenApi annotations.
My endpoint: {{url}}/qualification/{qualification_id}/holder/{holder_id}
The {holder} parameter is optional. If only the {qualification_id } parameter is supplied, a list of people that have received the qualification is returned, e.g.:
{{url}}/qualification/156/holder returns
<holder>
<holder>
<id>34</id>
<name>Tim</name>
<expired>false</expired>
</holder>
<holder>
<id>87</id>
<name>Andy</name>
<expired>false</expired>
</holder>
<holder>
<id>346</id>
<name>Ralph</name>
<expired>true</expired>
</holder>
<holder>
For this my response annotation is:
#OA\Response(
response=200,
#OA\JsonContent(
type="array",
#OA/Items(ref="#/components/schemas/QualificationHolder")
)
)
However, if the {holder_id} parameter is also supplied, only that specific qualification record holder is returned e.g.:
{{url}}/qualification/156/holder/346 returns:
<holder>
<id>346</id>
<name>Ralph</name>
<expired>true</expired>
</holder>
For this my response annotation would be:
#OA\Response(
response=200,
#OA\JsonContent(ref="#/components/schemas/QualificationHolder")
)
My problem is that I don't know how to combine these so that the documentation generated by using the OpenApi annotations indicates that the response could be EITHER of those options, and I can't find any documentation on line to indicate anything, either. Everything I find points me towards how to set up the json/yaml file, which is not what I need for this.

After digging through the zircote/swagger-php code making some assumptions while looking at the examples, I got it working by using the following annotation:
#OA\Response(
response=200,
#OA\JsonContent(
oneOf={
#OA\Schema(ref="#/components/schemas/QualificationHolder"),
#OA\Schema(
type="array",
#OA\Items(ref="#/components/schemas/QualificationHolder")
)
}
)
)

Related

How to perform OData V2 read with date as part of the entity primary keys [duplicate]

This question already has an answer here:
Performing OData V2 methods with "Edm.DateTime" as part of primary keys
(1 answer)
Closed 23 days ago.
I am confused on the date format to be used while invoking OData read operation where parameters are mentioned within entityset brackets. Would be great if you can paste your answer against each
How to use ODataModel's read() method if we have values to be passed within the entity set parameters?
var sPath ="/EMP_DETAILSSet(Empid='50160458'/*, ...*/)";
oBackEndModel.read(sPath, {
success: this._fGetDetailsSuccess.bind(this),
error: this._fBackEndInvocationError.bind(this)
});
Is this the approach to be followed? Or do we have any other approach?
How to set date as entity set key parameter with OData? Please correct the below code snippet (which gives me bad request error at runtime) where dBegDate and dEndDate are JS standard date objects.
var sPath ="/EMP_DETAILSSet(Empid='50160458',Begdate="+ dBegDate.toJSON() + ",Enddate=" + dEndDate.toJSON() + ",HAFId=' ')";
oBackEndModel.read(sPath, {
success: this._fGetDetailsSuccess.bind(this),
error: this._fBackEndInvocationError.bind(this)
});
How to execute multiple expand operation along with the entityset parameters mentioned above? Please fix the error in the below code as it is not working for me.
var sPath ="/EMP_DETAILSSet(Empid='50160458',Begdate="+ dBegDate.toJSON() + ",Enddate=" + dEndDate.toJSON() + ",HAFId=' ')";
oBackEndModel.read(sPath, {
urlParameters: {
$expand: "NAVTODETAIL,NAVTOPROFILE,NAVTOREPORTEES"
},
success: this._fGetDetailsSuccess.bind(this),
error: this._fBackEndInvocationError.bind(this)
});
Further updates
I have followed the suggestion b Sunil. sPath looked as follows at runtime:
"/EMP_DETAILSSet(Empid='50160458',Begdate=datetime'2014-03-11T14:49:52',Enddate=datetime'9999-12-31T14:49:52',HAFId=' ')"
When I tried this, it gave me the following error:
2018-06-13 10:56:31.872300 The following problem occurred: HTTP request failed404,Not Found,{"error":{"code":"005056A509B11EE1B9A8FEC11C21D78E","message":{"lang":"en","value":"Resource not found for the segment '49:52',Enddate=datetime'9999-12-31T14:49:52',HAFId=''."},"innererror":{"transactionid":"5B20F78A93457852E10000000ACD4014","timestamp":"20180613052610.2725590","Error_Resolution":{"SAP_Transaction":"Run transaction /IWFND/ERROR_LOG on SAP Gateway hub system and search for entries with the timestamp above for more details","SAP_Note":"See SAP Note 1797736 for error analysis ..."}}}}
Do you know why?
Please note that the following URL works fine and returned the result when executed from SAP Gateway Client:
/sap/opu/odata/XXX/YYYY_SRV/EMP_DETAILSSet(Empid='50160458',Begdate=datetime'2014-03-11T14:49:52',Enddate=datetime'9999-12-31T14:49:52',HAFId=' ')?$expandNAVTODETAIL,NAVTOPROFILE,NAVTOREPORTEES&$format=json
First thing is to check, what is the primitive type defined in you SAP Netweaver gateway.
Most probably, it will beEdm.DateTime. You can get this info using $metdata call on service.
OData has standard representation of Edm.DateTime
datetime'yyyy-mm-ddThh:mm[:ss[.fffffff]]'
NOTE: Spaces are not allowed between datetime and quoted portion. datetime is case-insensitive
Example : datetime'2000-12-12T12:00'
If its JSON Format representation,
Example: "FlightDate": "/Date(1354665600000)/"
It should look something like:
var sPath = "/EMP_DETAILSSet(Empid='50160458',Begdate=datetime'2014-03-11T14:49:52',Enddate=datetime'2014-03-11T14:49:52',HAFId = ' ')";
oBackEndModel.read(sPath, {
urlParameters: {
$expand: "NAVTODETAIL,NAVTOPROFILE,NAVTOREPORTEES"
},
success: jQuery.proxy(this._fGetDetailsSuccess, this),
error: jQuery.proxy(this._fBackEndInvocationError, this)
});

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 }

Implementing `startCursor` and `endCursor` in Relay

We have a graphql server not written in javascript, which we're trying to conform to the relay specification. startCursor and endCursor show up in a few examples but not in any official docs; based on my reading of https://github.com/facebook/relay/issues/372 those fields are basically deprecated, but they do show up in some code still. Do we have to implement them:
to be spec compliant?
to work with existing clients?
to be spec compliant?
As you point out, these fields don't appear in the spec, so they must not be required to conform to the spec. I conclude this because I think that's the only conclusion any serious authors of a spec should want you to draw from the absence of something from their spec.
to work with existing clients?
This, of course, is a different, more practical question :). The only client that I am aware of that uses the Connection spec is Relay, and Relay Modern requires these fields. Since these values are used by the PaginationContainer, the Relay Modern compiler requires them on any field marked with the #connection directive:
[END_CURSOR, HAS_NEXT_PAGE, HAS_PREV_PAGE, START_CURSOR].forEach(
fieldName => {
const pageInfoField = pageInfoType.getFields()[fieldName];
invariant(
pageInfoField &&
SchemaUtils.getNullableType(pageInfoField.type) instanceof
GraphQLScalarType,
'RelayConnectionTransform: Expected type `%s` to have an ' +
'%s field for which the type is an scalar in document `%s`.',
pageInfo.type,
fieldName,
definitionName,
);
}
);
I never remember which of endCursor and startCursor corresponds to which pagination direction. Since they are not documented in the spec, you can look to graphql-relay-js for this information:
startCursor: {
type: GraphQLString,
description: 'When paginating backwards, the cursor to continue.'
},
endCursor: {
type: GraphQLString,
description: 'When paginating forwards, the cursor to continue.'
},
No, they're not deprecated, and they do show up in the docs. What that issue says is that you don't have to implement them if you don't want to use them directly in your app, because Relay is going to query the cursor for each edge in a connection automatically, and will use that when making requests during pagination.

How to add headers to odata get service

I am working on following odata service:
https://10.49.78.69:8083/gateway/odata/SAP/SOA_LOGIN_GET_DATA;v=1/InspectionSet
This service runs only when following four headers are defined.
InterfaceID ADFCA_CRM_SBL_023
LanguageType ENU / ARA
UserName SHEENAR
Password Sheenar#123
I have tried using filters as follows but no success.
[https://10.49.78.69:8083/gateway/odata/SAP/SOA_LOGIN_GET_DATA;v=1/InspectionSet?$filter=UserName eq 'SHEENAR' and Password eq 'Sheenar#123' and InterfaceID eq 'ADFCA_CRM_SBL_023' and LanguageType eq 'ENU'
Guess headers have to be declared specifically.
Kindly suggest how these headers can be written while setting data to model in SAP UI5.
after creating the instance oDataModel,
var oDataModel = new sap.ui.model.odata.ODataModel(sServiceUrl, mParameters);
oDataModel.setHeaders(mHeaders)
Parameters:
{object} mHeaders :the header name/value map.
Read more here

Jersey POST operation with PathParam and JSON Object

By design, GET operation should be used only for read Only operation. Howeevre,i am looking for a plausible way of implementaion of following.Implement a POST operation that can be called as it is mentioned below
POST /my-store/order/D : where D is the day the customer place an order
Request: POST /my-store/order/14
{
"customer" : "XYZ",
"order" : {
"item1" : 2
}
}
I tried implementing using below function
#Path("/D")
#POST
#Consumes({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
#Produces({ MediaType.APPLICATION_JSON })
public Response submitOrder(#PathParam("D") int elapsedDays, #Context UriInfo uriInfo, Order orderInfo){
..........
}
But the above implementation does not seem to working. When I try to test the implementation using MyEclipse REST explorer ,it does not offer option to pass in Order object but allow 'D' parameter only. However, if #PathParam and #Path is removed then it works perfectly fine i.e. allows to consume JSON Order object.
But,the requirement is to pass the days as Path parameter and Order object as JSON input in POST request.
Looking for suggestion on implementation approach and design approach.
Thanks in advance
For one thing, your path should be configured like this:
#Path("/{D}")
I assume your extended ellipses means you have some method parameter that represents the deserialization of your order.

Resources