OpenAPI cookie parameter serialization - serialization

I'm trying to implement spec-compliant parameter serialization for OpenAPI cookie parameters.
My only source for this is the docs: https://swagger.io/docs/specification/serialization/#cookie
In the description I'm seeing this line:
An optional explode keyword controls the array and object serialization
However the table below only defines array and object serialization, when explode is false.
What does this mean?:
Is cookie serialization with explode = true defined? If so could you please link docs?
If not, am I correct in saying, that explode = true basically "disables" array and object serialization, and has no effect on primitive serialization?
If neither of these, then what is the situation with explode?
I hope an OpenAPI expert can shed some light on this, thank you!

Cookie serialization is defined but unfortunately not well thought out, as a result some forms of it don't make much sense. One of the specification authors admits that they "never really thought anyone would go through the trouble of describing objects in cookies in an exploded way".
In a nutshell, cookie serialization follows the same rules as query parameters with style: form.
When using explode: true:
A cookie parameter named param with the array value [3, 4, 5] would be sent as:
Cookie: param=3&param=4&param=5
A cookie parameter named param with the object value {"foo": "test", "bar": 5} would be sent as:
Cookie: foo=test&bar=5
Note that the parameter name (param) is lost in this case.
As you may notice, both methods deviate from the standard Cookie header format which expects semicolon-separated name=value pairs:
Cookie: [cookie-name]=[cookie-value]; [cookie-name]=[cookie-value];...
In other words, OpenAPI's exploded form of cookies is not quite compatible with cookie parsers. For example, an OpenAPI-formatted exploded array cookie Cookie: param=3&param=4&param=5 would be parsed by a cookie parser as param = 3&param=4&param=5 - which is not what an API developer would expect.
The problems with cookie serialization are being discussed here:
Default 'explode' for cookie parameters?
Feel free to provide your implementer's feedback.

Related

query parameter books accepts an array of enum values. Is there a way I can give 400 bad request if a particular combination of values is received?

books?:
type: array
items:
enum: [a,b,c,d]
Let's say I want to give a bad request whenever b,c come together. Eg:
[a,b,c,d] -> invalid request
[a,b,c] -> invalid request
[b,c] -> invalid
In short, if a request has both b & c together, can 400 be displayed using RAML ?
You can declare different types of valid combinations and then use them as possible input types.
Something like:
types:
validCombinationA:
type: array
items:
enum:
- a
- b
- d
validCombinationB:
type: array
items:
enum:
- a
- c
- d
And then:
books?:
type: validCombinationA | validCombinationB
That way is going to fail whenever you use an invalid combination.
If the valid combinations are static and the probability of new future values is small, then it's not a big deal using this approach but if that's not the case, you will need to create X number of types for each valid combination.
Maybe it worths a thought of consideration look for other possibilities for your use case (eg: with OAS that can be done with the usage of elements such as oneOf, anyOf, allOf, not).
If the validation is quite simple, then I'd prefer to do it that way instead of using the Validation Module or something else inside a flow given that probably has an impact on performance (do some quick tests to verify it).
That's not possible. RAML is not expected to be used to define data validation. RAML only define validations of types and the structure of requests. You need to implement that kind of rule in the implementation of the API. In this particular case it seems that you are using Mule to implement the API. Inside the Mule application project you need to perform the validation in the flows.

References to IDs in APIs responses, null or 0?

I consider myself that 0 is not a good thing to do when returning information from an API
e.g.
{
userId: int|null
}
I have a colleague that insists in that userId should be 0 or -1, but that forces a system to know that the 0 means "not set", instead of null which is universally known as not set.
The same happens with string params, like logoUrl. However, in this case I think it is acceptable to have an empty string instead of null if the variable is not set or was unset.
Is there bibliography, standards, etc, that I can refer to?
I'm not aware of any standard around that, but the way I take those kind of decisions is by thinking about the way consumer services would read this response, the goal being to provide a very smooth and clean consuming workflow. This exercise can even be transformed into a documentation for your API consumers.
In your case, instead of returning a null/0 field, I would simply remove that field altogether when it's empty and let the consumers explicitly mark that field as optional in the model they use to deserialize this response.
In that way, they'll explicitly have to deal with those optional fields, than relying on the API to always provide a value for them.

Use encoded object query param for GET request

While designing the API with with the team a suggestion was forwarded in regards to some complex query parameters that we sent which need to be encoded as objects, arrays of objects, etc. Suppose I have a route GET /resource/ and I want to apply a set of filters directly in the query params. The object literal structure of this filter would be something like
filter: {
field1: {
contains: 'value',
notin: ['value2', 'value3']
},
field2: {
greaterThan: 10
}
}
Encoding this in the url, via a query string parser such as the qs node module that express.js uses internally, would be cheap on the backend. However 1) The generated url is very hard to read, if a client wants to connect with the API he would need to use an encoding library and 2) I don't think I ever encountered the use of query params like this, it looks a little bit of overengineered and I'm not sure how used it is and if it is really safe.
The example above would yield query params such as:
GET /resource/?field1%5Bcontains%5D=value&field1%5Bnotin%5D%5B0%5D=value2&field1%5Bnotin%5D%5B1%5D=value3&field2%5BgreaterThan%5D=10
Does this practice of sending url query parameters that happen to be complex objects have some standards or best practices?
We implemented a different solution for filtering, when the list of possible parameters was very long. We ended up doing it in two steps, posting the filter and returning a filter ID. The filter ID could then be used in the GET query.
We had trouble finding any best practices for this.

What's the best way to wrangle path patterns in Restkit

I'd like to be able to specify a string, let's say
NSString * pathPattern = /api/elements/:id/subelement/:type
and call a simple function
[pathPattern build:#{#":id" => id, #"subelement" => subelement}]
to generate the URL path.
Obviously I can build a simple category to do this, but does something exist that handles such things in a generic way, and maybe has additional useful features for this kind of thing that I haven't thought of at this time?
Yes, RestKit already injects parameters into path patterns. Internally it uses SOCKit to perform this parameterisation.
It actually uses exactly the format you have in the question and where the parameter names match keys on the supplied object for mapping.
The path pattern can also be used during response mapping to take values back out of the request URL.

Modifying ServiceStack's JSON output

I have to build a REST service with ServiceStack; the responses must have a certain format. Both JSON and XML are to be supported. The standard serializers do not return the response in the format I need.
For JSON, it would be enough to wrap the result, e.g. if a function returns a list of Site objects, the JSON serializer gives me [{...}, ...], but I need {"Sites": [{...}, ...]}. The requested content-type would be "Sites+json" in this case. For other functions, "Sites" would be replaced by something else.
How can I achieve this?
Edit:
The XML has to be the direct "translation" of the JSON, like
<Sites>...</Sites> instead of {"Sites":...}.
The standard XML serialization works differently, it always puts in the data type as well.
Has anyone an idea how to do this? I guess I have to write my own XML serializer and map all my XML types (like Sites+xml,...) to it?