MichalLytek / MichalLytek/type-graphql
Accessing to resolver metadata in middleware
- Dominant language
- TypeScript
- Stars
- 8.1k
- Forks
- 672
- PR merge metrics
- No merged PRs in 30d
Description
Providing metadata/resolver information into a middleware operation might have some benefits for extended use cases.
**Example Use Case:**
In this example I wanted to change `level` field to a fixed value if user is not an admin.
Decorator example;
```ts
function ValueUnlessAdmin(val: any) {
return function(inputCls: any, field: any) {
Reflect.defineMetadata("valueUnlessAdmin", val, inputCls.constructor, field);
};
}
```
InputType example;
```ts
@InputType()
class CreateUserInput {
@Field()
@ValueUnlessAdmin("member") // Creates metadata
level: string;
}
```
Middleware example;
```ts
class SetValues implements MiddlewareInterface {
async use({ context, args }: ResolverData, next: NextFn) {
// At this point one might want to use metadata
return next();
}
}
export const schema = buildSchemaSync({
resolvers: [UserResolver],
globalMiddlewares: [SetValues],
});
```
Here's a suggested workaround by @19majkel94
```
> technically you can create a class decorator to mark an input class that it has special decorator like @ValueUnlessAdmin
> they both can use Reflect.defineMetadata to store some data attached
> and then in middleware you can browse the info object to search if the mutation use an input type with this custom decorator
> middlewares don't know if next is a middleware or a resolver so they have no access to compiled resolver params
> so you can't get array of params with instances of classes and make some checks
> and input type field have no middlewares or guards and input types are only data transfer object, they're not executed, no logic there
```
This workaround did the trick. That being said, it could be easier to realize such intentions and may be more if metadata/resolver information can be accessed in the middleware.
Contributor guide
Research direction
No repository file or test is named. Start with the MiddlewareInterface.use example and the ResolverData, NextFn, and buildSchemaSync entry points shown in the issue, then trace how global middleware is connected to resolvers. Done means middleware can access the relevant resolver or metadata information needed for the described input-field use case, with behavior demonstrated by a test or example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, typescript
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100