MichalLytek / MichalLytek/type-graphql

Custom argument parameter decorator

Open
#629 0 comments 0 reactions 0 assignees View on GitHub
Community :family_man_girl: Discussion :speech_balloon: Enhancement :new:
Dominant language
TypeScript
Stars
8.1k
Forks
672
PR merge metrics
No merged PRs in 30d

Description

I find using regular method & parameter decorators rather hacky when trying to work with arguments as they are disconnected.

For instance in my code below, I need to check that the supplied user_id is permitted to be deleted by the user who made the request (gotten from context).
```ts
/** @typegraphql Delete a user from the application.
*/
@UserAccessControl('DELETE', 'user_id')
@Mutation(_returns => User, {nullable: true})
deleteUser(@Arg('user_id') user_id: string): User {
const user = this.userSvc.getUserByID(user_id);
return this.userSvc.deleteUser(user_id) ? user : null;
}
```
The problem is that the AccessControl decorator doesn't enforce that 'user_id' be a specified parameter, it just happens to be so, and I later have to check whether the property exists on the args object in the resolver function. 'user_id' could be anything on either AccessControl or Arg.

It would be nice to have a way to define custom decorators that behave like Arg, i.e they add the parameter to the schema (in contrast to regular parameter decorators). This would allow the above to become just `deleteUser(@UserAccessControl('DELETE', 'user_id') user_id: string)`, where UserAccessControl is something analogous to:
```ts
const UserAccessControl = (requiredLevel, name, options): ParameterDecorator => {
return createArgParamDecorator(name, async ({context}, argValue) => {
const userLevel = getUserLevelForUser(context.req.user_id, argValue); // Use DI / Container.get() etc.
if (userLevel < requiredLevel) {
throw new ForbiddenError();
}
return argValue; // this means the requesting user is permitted to perform 'DELETE' level operations on the user_id argValue
}, options);
}
```

I've created an implementation and example of this feature here (missing tests):
https://github.com/etylermoss/type-graphql/commit/14c2a232137f81d910a9ef7f2fe124f24bfe9f45

Contributor guide

Open the contributing guide

Research direction

Start by reviewing commit 14c2a232137f81d910a9ef7f2fe124f24bfe9f45 and its example implementation. Trace how the proposed decorator integrates with the existing Arg decorator and resolver schema generation, then add the missing tests. Done means a custom parameter decorator adds the argument to the schema and can inspect its value and context before returning it or throwing an error.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, typescript
Domain
api, backend-api-design
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.