Reputation: 179
I'm trying to develop a decorator to know if some params are valid.
Here is my method,
getUsers(offset, limit, orderBy, sort){
....
}
I need to check if orderBy is 'createdAt' or 'updatedAt' if not, a http response will be send.
Same thing for sort, it need to be 'ASC' or 'DESC'.
So, i don't know how can I use decorator to help me to remove some line in my code, it's a small block but it's cleaner I think. Currently here is my block to check
if (!includes(this.orderByFields, orderBy)) {
return Utils.HttpError.badRequest(`You are allowed to order by [ ${this.orderByFields.join(', ')} ] only.`);
}
Maybe is not possible to do it, thanks by advance :-)
Upvotes: 0
Views: 3074
Reputation: 455
You should be able to do something like this:
type ApiFunction = (offset: number, limit: number, orderBy: string, sort: string) => any;
const orderByFields = ["createdAt", "updatedAt"];
function validateRequest() {
return function(_target: any, _propertyName: string, descriptor: TypedPropertyDescriptor<ApiFunction>) {
const originalMethod = descriptor.value!;
descriptor.value = function(offset, limit, orderBy, sort) {
if (!orderByFields.includes(orderBy)) {
return "Bad Request";
}
return originalMethod.bind(this)(offset, limit, orderBy, sort);
};
};
}
This also makes sure that you can only apply the decorator to methods with a matching signature.
Usage example:
class Foo {
@validateRequest()
getUsers(offset: number, limit: number, orderBy: string, sort: string): string {
return "Result";
}
}
Apart from this you might want to try and enforce the orderBy
and sort
parameters on the type-level (and if you're the only consumer of this API then you might not even need the decorators):
function getUsers(offset: number, limit: number, orderBy: "createdAt" | "updatedAt", sort: "ASC" | "DESC") {}
Upvotes: 1