A GraphQL provider for the Adonis framework
This library provides an easy way to start using GraphQL with AdonisJS without losing the essence of it.
adonis install adonis-gql
In the installation the start/graphql.js
and start/gqlKernel.js
files will be created.
Register the provider in start/app.js
:
const providers = [
// ...
'adonis-gql/providers/GQLProvider'
];
Record the preLoads
needed in server.js
:
new Ignitor(require('@adonisjs/fold'))
.appRoot(__dirname)
/* Register preLoads to GQLProvider */
.preLoad('start/graphql.js')
.preLoad('start/gqlKernel.js')
/* End */
.fireHttpServer()
.catch(console.error)
To use adonis-gql
you need to set Controllers
and Schemas
and configure them in the start/graphql.js
file.
You can add middlewares
to your resolvers, they can be global or named, so you need to create a middleware that has the gqlHandle
method and register it.
class Auth {
async gqlHandle (resolve, root, args, ctx, info) {
const result = await resolve(parent, args, ctx, info)
return result
}
}
module.exports = Auth
To use them you need to register them in the start/gqlKernel.js
file:
// to use global
Gql.registerGlobal(['App/Middleware/Auth'])
// to use named
Gql.registerNamed({
auth: 'App/Middleware/Auth'
})
The resolvers are in the directory app/Controllers/Gql
.
Here the resolvers are separated by Queries
, Mutations
or a specific type.
The file for Queries
of Post
staying in app/Controllers/Gql/Queries/PostController.js
:
class PostController {
async posts(parent, arg, ctx) {}
}
module.exports = PostController
The file for Mutations
of Post
staying in app/Controllers/Gql/Mutations/PostController.js
:
class PostController {
async addPost(parent, arg, ctx) {}
}
module.exports = PostController
For the sake of organization, adonis-gql create directories to separate the types app/Controllers/Gql/Queries
and app/Controllers/Gql/Mutations
.
You can add middlewares inside the Controller class with the static
method called middlewares
and it needs to return an object containing the keys with the previously registered middlewares:
class PostController {
async posts(parent, arg, ctx) {}
static middlewares () {
return {
posts: ['auth']
}
}
}
module.exports = PostController
Note that to add a middleware to all methods of the class use the keyword all
:
static middlewares () {
return {
all: ['auth']
}
}
The schemas are in the directory
app/Schemas
.
The schema
file should have the type name (a suggestion, not an obligation) and always end with the extension .graphql
.
Following the example above, the file for the schema
of Post
staying in app/Schemas/Post.graphql
:
type Query {
posts: [Post]
}
type Mutation {
addPost(title: String!, content: String!): Post
}
type Post {
id: Id
title: String
content: String
}
The directives are in the directory app/Directives
. The file for Deprecated
directive staying in app/Directives/DeprecatedDirective.js
:
'use strict'
const SchemaDirectiveVisitor = use('SchemaDirectiveVisitor')
class Deprecated extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
field.isDeprecated = true;
field.deprecationReason = this.args.reason
}
visitEnumValue(value) {
value.isDeprecated = true;
value.deprecationReason = this.args.reason
}
}
module.exports = Deprecated
The example was taken from Implementing schema directives.
/!\
Always a directive will be extended SchemaDirectiveVisitor /!\
For effective use of resolvers
and schemas
it is necessary to register them in start/graphql.js
:
const Gql = use('Gql')
// Here it has to be exactly that of the file defined in app/Schemas
Gql.schema('Post')
Gql.query('Post', 'Queries/PostController')
Gql.mutation('Post', 'Mutations/PostController')
// Maybe you prefer to organize more.
Gql.schema('Post', () => {
Gql.query('Queries/PostController')
Gql.mutation('Mutations/PostController')
})
You can add middlewares to the schemas and resolvers respectively, note that the middlewares called in the schema will be applied to the resolvers that involves.
Gql.schema('Post', () => {
Gql.query('Queries/PostController').middleware(['auth'])
Gql.mutation('Mutations/PostController').middleware(['auth'])
})
It's the same as:
Gql.schema('Post', () => {
Gql.query('Queries/PostController')
Gql.mutation('Mutations/PostController')
}).middleware(['auth'])
Following the same train of thought you can add the directive
in AdonisGql. The first argument is its name and the second its controller, register them in start/graphql.js
:
const Gql = use('Gql')
Gql.directive('deprecated', 'DeprecatedDirective')
Finally, it is necessary to configure the handle
do adonis-gql
in the route that you want.
In the file start/routes.js
:
// ...
const Gql = use('Gql')
Route.post('/', ctx => Gql.handle(ctx))
// If you want a playground
Route.get('/graphiql', ctx => Gql.handleUi(ctx))
Command | Description | Options |
---|---|---|
adonis gql:schema <name> |
Make a new schema to graphql | -r Generate resolvers query and mutation for the schema-q Generate only query resolver for the schema-m Generate only mutation resolver for the schema |
adonis gql:resolver <name> |
Make a new resolver to graphql | -q Generate only query resolver for the schema-m Generate only mutation resolver for the schema |
adonis gql:directive <name> |
Make a new directive to graphql | |
adonis gql:middleware <name> |
Make a new middleware to graphql |
Thank you very much to the creators of AdonisJS for creating this wonderful framework.
I