@dysfunctionl/adonis-grapple v0.0.2
Adonis Grapple
Grapple is an addon for Adonis that wraps around apollo-server-adonis with a some extra bells and whistles. It is also heavily inspired by adonis-graphql
Contents
- Main Features
- Setup Install Provider Dependencies Config
- Usage Getting Started Routing Helpers DataLoaders
Main Features
- GraphQL Server
- Schema stitching
- Dataloader
- Helpers
- Commands for generating boiler plate
Setup
Install
Install Grapple
adonis install @dysfunctionl/adonis-grapple
Register the provider inside start/app.js
file
const providers = [
'@dysfunctionl/adonis-grapple/providers/GrappleProvider'
]
Run the setup to create the folder structure based on config/grapple.js
# Tack -r to replace the routes file to include GraphQL and GraphiQL
adonis grapple:setup
Start the server
adonis serve --dev
Provider
Like any other provider, you need to register the provider inside start/app.js
file.
const providers = [
'adonis-grapple/providers/GrappleProvider'
]
Dependencies
This module has dependencies on @adonisjs/bodyparser
.
Config
The configuration is saved inside config/grapple.js
file. Tweak it accordingly.
'use strict'
module.exports = {
// Resolvers directory
'resolvers': 'app/GraphQL/Resolvers',
// Schma types directory
'types': 'app/GraphQL/Schema',
// Connections directory
'connections': 'app/GraphQL/Schema/connections',
// DataLoaders folder
'loaders': 'app/GraphQL/DataLoaders',
// Schema stitching file
'schema': 'app/GraphQL',
// Only use if you have defined the same type multiple times in
// different files and wish to attempt merging them together.
'merge': false
}
Usage
Getting Started
Start by creating your schema, resolver and dataloader files, you can do this using commands or create them yourself (see command section for examples)
Once you have your files ready to go, you have to register them through app/graphql/index.js
(can be changed in config under schema
)
(uses Merge GraphQL Schemas for stitching, see for more docs on schemas and resolvers.)
Example:
exports.types = [
requireGraphQL('user.type')
]
exports.resolvers = [
requireResolver('user.resolver')
]
exports.dataLoaders = {
userLoader: requireLoader('user.loader')
}
Routing
To actually setup your server routers, open start/routers.php
and use something similar to the following:
(uses apollo-server-adonis, see for more docs)
GraphQL:
const Route = use('Route')
const GraphQLServer = use('Grapple/GraphQLServer')
// GraphQL Endpoint
Route.route('/graphql', (context) => {
return GraphQLServer.handle(context, {
// OPTIONS
})
}, ['GET', 'POST'])
GraphiQL:
npm i --save-dev apollo-server-module-graphiql
(see here for docs on options)
const Env = use('Env')
const GraphiQL = require('apollo-server-module-graphiql')
// GraphiQL Endpoint
if (Env.get('NODE_ENV') === 'development') {
Route.get('/graphiql', ({ request, response }) => {
const options = {
endpointURL: '/graphql',
}
return GraphiQL.resolveGraphiQLString(request.originalUrl(), options, request).then(graphiqlString => {
response.header('Content-Type', 'text/html').send(graphiqlString)
}, error => response.send(error))
})
}
Helpers
requireGraphQL('user.type') // Imports user.type.graphql from `schema` Folder
requireConnection('connections/user.connection') // Imports user.connection.graphql from `schema/connections` folder
requireResolver('user.resolver') // Imports user.resolver.js from `resolvers` folder
requireLoader('user.loader') // Imports user.loader from `dataloaders` folder
DataLoaders
See DataLoader for docs.
Example:
const User = use('App/Models/User')
const _ = require('lodash')
module.exports = async (keys) => {
const users = await User.query().whereIn('id', keys).fetch()
const grouped = _.groupBy(users.rows, 'id')
return keys.map(k => grouped[k] || [])
}
Usage:
const DataLoader = use('Grapple/DataLoader')
const userLoader = DataLoader.get('userLoader')
return userLoader.load(1).then(...)
Commands
Schemas
Create a boilerplate schema file
Usage:
adonis grapple:schema User
# Create extra resources by tacking any of the following
-r --resolver
-c --connection
-d --dataloader
Example:
# app/graphql/schema/user.type.graphql
type User {
}
type Query {
}
type Mutation {
}
Connections
Create a boilerplate connection file
Usage:
adonis grapple:connection User
Example:
# app/graphql/schema/connections/user.connection.graphql
type UserConnection {
edges: [UserEdge]
pageInfo: PageInfo!
}
type UserEdge {
cursor: String!
node: User!
}
Resolvers
Create a boilerplate resolver file
Usage:
adonis grapple:resolver User
Example:
// app/graphql/resolvers/user.resolver.js
'use strict'
module.exports = {
Query: {
//
},
Mutation: {
//
},
}
DataLoaders
Create a boilerplate dataloader file
Usage:
adonis grapple:resolver User
Example:
// app/graphql/dataloaders/user.loader.js
'use strict'
module.exports = async (keys) => {
}