Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Parsing of Array Query Parameters for REST Applications and OpenAPI Specification #3491

Unanswered
Mathdrquinn asked this question in Q&A
Discussion options

I'm curious how the community handles documenting and consuming array query parameters.

The documentation is very clear on approach for leveraging, for example, $select within an application:

app.service('messages').find({
 query: {
 $select: ['text', 'userId']
 }
})

I find the translation to REST query parameters confusing. There is an extra set of square bracket required: GET /messages?$select[]=text&$select[]=userId.

The syntax, according to OpenAPI, seems to hint at an object query parameter in the deepObject style, while the docs seem to align with a style: form, explode: true format.

The helpful feathers-swagger package generates a swagger UI that similarly doesn't understand how to parse and handle array query syntax. The UI generates that same query as GET /messages?$select=text&$select=userId. This is valid, and returns results, but when requesting a single $select value, the query validators throw, saying they require an array.

tldr; How do you document query parameters that take arrays in a way that is OpenAPI 3.X compliant and aligns with Feather's documentation?

This framework has been a ton of fun to use and learn. Learning how you all navigate this finer detail could really help my projects easily integrate into the the vast tooling surrounding OpenAPI specifications.

Thanks!

You must be logged in to vote

Replies: 1 comment 5 replies

Comment options

To make the problem slightly more complex, in OpenAPI 3.X nested query parameters are not supported. I'm wondering if the best approach is to flatten the query syntax into many options. Something like:

{
 "//": "rest of spec",
 "parameters": [
 {
 "in": "query",
 "name": "$sort[id]",
 "schema": { "type": "integer", "minumum": -1, "maximum": 1 }
 },
 {
 "description": "Number of results to skip",
 "in": "query",
 "name": "$sort[text]",
 "schema": { "type": "integer", "minumum": -1, "maximum": 1 }
 },
 {
 "description": "Number of results to skip",
 "in": "query",
 "name": "$sort[created]",
 "schema": { "type": "integer", "minumum": -1, "maximum": 1 }
 }
 ]
You must be logged in to vote
5 replies
Comment options

We found it's always better to be explicit so that would make sense. As for array handling, this should be the same behaviour (and configurability using the qs package) as in most other NodeJS framework I am aware of. For the case for a single select, I usually ended up normalizing any primitive value for $select into an array before validation.

Comment options

@daffl thanks for the engagement.

I think the conclusion, then is that feathers and feather-swagger won't seamlessly integrate with tools that are strictly OpenAPI 3.0 complaint. Additional middleware, hooks, post-processing, etc would be required to marry the usage of qs internally to the OpenAPI ecosystem.

If anyone has built something to this effect, or aware of an exiting tool to bridge the gap between the two, I'd appreciate you sharing.

Comment options

It's a bit surprising that the qs package doesn't seem to be OpenAPI spec complaint. Still to get things like GET /messages?$select=text&$select=userId and GET /messages?$select=text should be fairly straightforward with something like this:

export const somethingQueryResolver = resolve<SomethingQuery, HookContext>({
 $select: async (value, user, context) => {
 if (value !== undefined) {
 return Array.isArray(value) ? value: [ value ]
 }
 }
})
Comment options

💯 agreed.

For reference OAI/OpenAPI-Specification#3052 (comment) I came across that confirms OpenAPI's more limited query parameter scope.

Thanks for that snippet. Definitely a good reference. I'd written something similar as a one-off, but realized I want something more broad to help assist with $in and $nin for all queryable fields.

Comment options

To be fair, we all experience similar necessary type guards in vanilla express where all query parameters must be optional, a primitive, or an array of primitives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /