Tsoa: Dynamic Query/Header Param

Created on 14 May 2019  路  11Comments  路  Source: lukeautry/tsoa

I have a request which should look like this

users/query?someKey=someValue&someKey2=someValue2

These are dynamic query params that I handle in the server. Is there any way to create this using tsoa?

I tried something like this -

export interface QueryFilters {
    [x: string]: string;
}
...
 public async get(
        @Query() filters?: QueryFilters
    ): Promise<User[]> {
        return getUsers(filters);
    }

but I'm getting error -

 Error: @Query('filters') Can't support 'refObject' type.
enhancement help wanted

Most helpful comment

The idea (getting the spec from an interface) is fine, we just need a way to indicate that it's a query param collection, not, for example, an object serialized from one query param.
I could see something like @Query('/') params: { one: string, two: number }, since it's impossible to use / as the name of a single query param.

If anyone wants to implement this, I'd be glad to review a PR adding this.

All 11 comments

I'm currently working on an implementation of refObject for @Query (and possibly @Header too) by "flattening" the properties as individual parameters and reassembling them at the server.

I have a very basic but (mostly) working implementation ready, which is good enough for my own project for now. When I have the time I'll add the missing parts and create a PR.

@HoldYourWaffle we鈥檇 love if you could submit your PR for this.
@dmitrirussu had a similar and interesting request here: https://github.com/lukeautry/tsoa/issues/324#issue-391707399

I also work with another team that would find this really valuable as they use OData filters. So suffice to say, you鈥檇 be quite the hero if you were to submit this! :)

Sorry for the late response, haven't touched this in a while due to summer break.

I don't remember much and I'm not able to really look into the code right now, but from what I remember my implementation was very basic and specific to my use-case. I'll see what I can do to fix it up and maybe make it more usable for other use-cases.

I believe that https://github.com/lukeautry/tsoa/issues/219#issuecomment-526403819 is a duplicate of this. I鈥檒l close that one to keep this open.

@Templum @anro87 when we introduce array like query params then this is the issue number to track. I鈥檓 cc鈥檌ng you so you鈥檙e not left out. We apologize that your original feature request was not added in a timely manner.

@WoH can you point me to where the changes in the code would need to be to get this working? Its currently blocking for me. Would be happy to work on it (maybe tonight/this weekend)

This should not be a blocker, albeit you'd have to write the OpenAPI for yourself. Assuming Express, but you can inject the Request (and look at req.headers) and add the Spec to your tsoa.json.
I'm not sure how the API should look like for this, the one suggested is a non-starter.
@Query() filters would be a query param called filters, as in ?filters=.
I could imagine resolving an interface here, but the approach would have to ensure a) you can still pull off individual query params, b) these would not be documented twice, c) the OpenAPI Spec is sound.

the one suggested is a non-starter.

It's very Javascript-esque to just get a params object. Would it not be possible to "break down" the interface/class given as a type? E.g. @Query queryObject: IQueryParams can be converted into @Query qObjectProp1: prop1Type, @Query qObjectProp2: prop2Type, ...

A possible conflict with this solution is when we have something along the lines of @Query params, @Query('paramName') myParam: paramType, breaking down the params object will yield a duplicate myParam. But I guess that's something easy to handle.

The idea (getting the spec from an interface) is fine, we just need a way to indicate that it's a query param collection, not, for example, an object serialized from one query param.
I could see something like @Query('/') params: { one: string, two: number }, since it's impossible to use / as the name of a single query param.

You are correct. I was a bit confused there because we're using nest.js decorators for our controllers and tsoa "automagically" works with those. A @QueryParams() decorator seems the logical way forward, but your idea of using a wildcard such as / is better (and also keeps things working with nest 馃槃 ).

The idea (getting the spec from an interface) is fine, we just need a way to indicate that it's a query param collection, not, for example, an object serialized from one query param.
I could see something like @Query('/') params: { one: string, two: number }, since it's impossible to use / as the name of a single query param.

If anyone wants to implement this, I'd be glad to review a PR adding this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jfrconley picture jfrconley  路  3Comments

caringdeveloper picture caringdeveloper  路  3Comments

jakubzloczewski picture jakubzloczewski  路  6Comments

eluft84 picture eluft84  路  6Comments

strongpauly picture strongpauly  路  3Comments