Is it possible to provide a path parameter in the @Route decorator? I am thinking about something like this:
@Route('/folder/{folderId}/file')
class FilesController {
@Get('{fileId}')
public async GetFileById(folderId: string, fileId: string): Promise<FileResponse> {
// Both parameters from the @Route and @Get are available here
...
}
}
This would be very handy to avoid some code duplication and would make routes configuration a bit cleaner.
At the moment I get the following error:
Generate swagger error.
Error: @Path('fileId') Can't match in URL: '{fileId}'.
This is not possible yet. The path from the route decorator is not passed on to the parameter validation. It seems like a sensible thing to do though. Would you be interested in implementing this?
Oh wait I didn't read it correctly, sorry my bad. I see you're mixing path variables with path variables
Original answer below:
You can use attributes on your parameters as well. This is how I did it and it works:
@Get('getShareAttachment/{attachmentId}')
public async getShareAttachment(@Request() request: express.Request,
@Path() attachmentId: string,
@Query() shareId: number) {
...
}
To avoid code bloat in tsoa, I nominate that we do not support this feature when it鈥檚 very easy for users to add the path parameter as follows:
@Route('/folder/')
class FilesController {
@Get('{folderId}/file/{fileId}')
public async GetFileById(folderId: string, fileId: string): Promise<FileResponse> {
...
}
}
Personally, I also find this version to be more readable. That being said, if there鈥檚 enough interest we can re-open the issue.
This is more of a philosophical problem. Consider the following example:
/api/v1/user/12/device/1/
I have user/{userId} at the beginning of everything. Now, how do you expect the @Route of DeviceController to look like, 'user' (like all other controllers) or 'user/{userId}/device'?
Yes, it鈥檚 a philosophical question that doesn鈥檛 have a clear answer.
For instance I have worked on many projects where routes to user/{userId} and user we鈥檙e both in the UserController. You seem to suggest that they should be different controller classes.
And that is certainly one logical approach, however, I鈥檓 not sure I want to introduce the additional scope to tsoa. Ever feature that is added is more that can regress and more unit tests that make the build slower. And since this would effect all routes it really increases the permutations of tests that needed to be added. So this is no longer open to discussion unless we get additional maintainers who are more willing to support this than I am.
@WoH what do you think about this?
I think we should allow this, keeping the checks around @Path() so it's still safe. (Either used in @Method or @Route at class level)
Not a big user of sub resources, so this is not on my todo list, but if you're interested, would be a great feature.
Only being able to delegate non-templated parts to the @Route probably feels really awkward if you have a controller for a subresource.
Most helpful comment
I think we should allow this, keeping the checks around
@Path()so it's still safe. (Either used in@Methodor@Routeat class level)Not a big user of sub resources, so this is not on my todo list, but if you're interested, would be a great feature.
Only being able to delegate non-templated parts to the
@Routeprobably feels really awkward if you have a controller for a subresource.