Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve inference of @Param when used with ParseUUIDPipe #1818

Open
1 task done
Delapouite opened this issue Feb 11, 2022 · 1 comment
Open
1 task done

Improve inference of @Param when used with ParseUUIDPipe #1818

Delapouite opened this issue Feb 11, 2022 · 1 comment
Labels

Comments

@Delapouite
Copy link

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

Hi

Nest.js controller handlers often have to deal with UUIDs in the params. Here's an example:

@Delete(`tenants/:tenantId/folders/:id`)
@ApiParam({ name: "tenantId", format: "uuid", type: "string" })
@ApiParam({ name: "id", format: "uuid", type: "string" })
async delete(
    @Param("tenantId", ParseUUIDPipe) tenantId: string,
    @Param("id", ParseUUIDPipe) id: string,
) {
    // …
}

As you can see, extra @ApiParam decorators are needed to help Swagger understand the fact that both tenantId and id params are expected to be uuid. But this information could be infer by the fact that we're using ParseUUIDPipe in @Param.

Describe the solution you'd like

It would be great to not have to repeat the same information twice. While generating the Swagger document, the exploration process should be able to deduce that @Param("id", ParseUUIDPipe) means that the id param is an UUID.

Therefore, @ApiParam decorators would not be needed anymore, and the resulting code would be more lightweight, while providing the precise information in the final Swagger doc:

@Delete(`tenants/:tenantId/folders/:id`)
async delete(
    @Param("tenantId", ParseUUIDPipe) tenantId: string,
    @Param("id", ParseUUIDPipe) id: string,
) {
    // …
}

Teachability, documentation, adoption, migration strategy

No response

What is the motivation / use case for changing the behavior?

DRY code.

Thanks

@mingo023
Copy link

mingo023 commented May 11, 2022

export function Id(name: string): any {
    return (target: any, key: string, descriptor: any) => {
        ApiParam({
            description: `${name} id`,
            example: 'Your custom example',
            name,
            required: false
        })(target, key, Object.getOwnPropertyDescriptor(target, key));
        return idParamDecorator(name)(target, key, descriptor);
    };
}

export const idParamDecorator = createParamDecorator((options: ParamOptions | string, ctx: ExecutionContext) => {
    let paramOptions = getParamOptions(options, 'id');
    const request = ctx.switchToHttp().getRequest();
    let id = request.params[paramOptions.key] || request.query[paramOptions.key];
    if (!id && paramOptions.nullable) {
        return id;
    }
    if (!isUUID(id)) {
        throw new UuidException(paramOptions.key);
    }
    return id;
});

@Delapouite I think we could customize Id decorator like this. So it will validate a valid uuid and add swagger to your controller too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants