Middlewares
Middlewares are similar to the Adonis Middlewares but they work in the context of a GraphQL operation.
There are executed in series before reaching the resolver. Every middleare can end the request or forward it to the next middleware.
You can find more information about Middlewares on the Official TypeGraphQL documentation
Examples
Logging
import { } from '@adonisjs/core'
import { } from '@adonisjs/core/logger'
import { , } from '@foadonis/graphql'
@()
export default class {
constructor(private readonly : ) {}
({ , }: , : ) {
const = .auth.user
if () {
this..(`Access: ${.fullName} -> ${..}.${.}`)
}
return ()
}
}Execution timing
The second argument of the use method will execute the rest of the stack allowing you to run actions after the execution of your operations. For example you could log the execution time.
import { } from '@adonisjs/core'
import { } from '@adonisjs/core/logger'
import { , } from '@foadonis/graphql'
@()
export default class {
constructor(private readonly : ) {}
async ({ }: , : ) {
const = .()
await ()
const = .() -
this..(`${..}.${.} [${}ms]`)
}
}Intercepting the result
Middleware also has the ability to intercept the result of a resolver's execution. It's not only able to e.g. create a log but also replace the result with a new value:
import { , } from '@foadonis/graphql'
import { } from '@adonisjs/core'
export default class {
async ({ }: , : ) {
const = await ()
if ( === 'ts.ed') {
return 'adonis'
}
return
}
}Guards
Guards are simply middlewares that does not call the next function so it never reaches the resolver. This is useful when you want to block access on specific conditions.
import { , } from '@foadonis/graphql'
import { } from '@adonisjs/core'
export default class {
({ }, ) {
if (.frameworkName === 'ts.ed') {
throw new ('Adonis is better')
}
if (.frameworkName === 'adonis') {
return 'AdonisJS'
}
return ()
}
}Attaching Middlewares
Resolver method
To attach middleware to a resolver method, use the @UseMiddleware decorator above the method declaration. It accepts an array of middleware that will be called in the provided order. You can also pass them without an array as it supports rest parameters:
import { , , } from '@foadonis/graphql'
import from '#graphql/middlewares/performance_logger_middleware'
import from '#graphql/middlewares/access_logger_middleware'
@()
export default class {
@(, )
@()
() {}
}Resolver
If you want to apply the middlewares to all the resolver's class methods, you can put the decorator on top of the class declaration:
import { , , } from '@foadonis/graphql'
import from '#graphql/middlewares/performance_logger_middleware'
import from '#graphql/middlewares/access_logger_middleware'
@(, )
@()
export default class {
@()
() {}
}ObjectType Field
You can also attach the middleware to the ObjectType fields, the same way as with the @Authorized decorator.
import { , , } from '@foadonis/graphql'
import from '#graphql/middlewares/access_logger_middleware'
@()
export default class {
@()
: string
@()
@UseMiddleware()
: string
}Global
You can apply middlewares globally using the globalMiddlewares option in your GraphQL configuration:
import { } from '@foadonis/graphql'
import from '#graphql/middlewares/access_logger_middleware'
export default ({
: [],
})