Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/unirakun/graphql-directives-middlewares
GraphQL directives as middlewares
https://github.com/unirakun/graphql-directives-middlewares
directive graphql middleware nantes order preserve sort sorted
Last synced: 2 months ago
JSON representation
GraphQL directives as middlewares
- Host: GitHub
- URL: https://github.com/unirakun/graphql-directives-middlewares
- Owner: unirakun
- Created: 2018-12-06T12:07:45.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T01:59:34.000Z (about 2 years ago)
- Last Synced: 2024-11-18T13:25:36.062Z (3 months ago)
- Topics: directive, graphql, middleware, nantes, order, preserve, sort, sorted
- Language: JavaScript
- Size: 1.57 MB
- Stars: 18
- Watchers: 4
- Forks: 1
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# graphql-directives-middlewares
> GraphQL directives as middlewares
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/graphql-directives-middlewares)](https://bundlephobia.com/result?p=graphql-directives-middlewares)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/unirakun/graphql-directives-middlewares/Quality)](https://github.com/unirakun/graphql-directives-middlewares/actions?query=branch%3Amaster) [![NPM Version](https://badge.fury.io/js/graphql-directives-middlewares.svg)](https://www.npmjs.com/package/graphql-directives-middlewares) [![Coveralls github](https://img.shields.io/coveralls/github/unirakun/graphql-directives-middlewares.svg)](https://coveralls.io/github/unirakun/graphql-directives-middlewares)## install
`yarn add graphql-directives-middlewares`
> You need to have `graphql` and `graphql-tools` installed on your project.
## why
We create this library because we needed our directives to be sorted at runtime.
We were on the case we needed to execute our `@auth` directive BEFORE our `@api` directive take place.With `graphql-directives-middlewares` you just have to declare, in your schema, the directives in order you want them to take place.
With this declaration:
```gql
type Query {
users: [User] @auth(requires: ADMIN) @api(name: "users")
}
```Your `@auth` directive will be called BEFORE the `@api` one.
If you invert `@auth` and `@api`, then `@api` directive will be called BEFORE the `@auth`, without changing your implementation!
## API
### createVisitFieldDefinition
`createVisitFieldDefinition(name: string, impl: (params, next) -> (...args))`
- `name`: the directive name you use in your `gql` schema
- `impl`: is a function that take `params` and `next` and return a function that is your graphql custom resolver
- `params` are your directives arguments
- `next` is the next resolver to call, like in a middleware engine### createVisitObject
`createVisitObject(name: string, impl: (params, next) -> (...args))`
- `name`: the directive name you use in your `gql` schema
- `impl`: is a function that take `params` and `next` and return a function that is your graphql custom resolver
- `params` are your directives arguments
- `next` is the next resolver to call, like in a middleware engine## usage
Example with a `@auth` directive
1. define your directive in the schema
```js
export default `
enum Role {
ADMIN
USER
VIEWER
}directive @auth(requires: Role = ADMIN) on FIELD_DEFINITION
`
```2. create your directive implementation
```js
import { GraphQLList } from 'graphql'
import { createVisitFieldDefinition } from 'graphql-directives-middlewares'export default createVisitFieldDefinition(
'auth',
(params, next) => async (...args) => {
const { requires: requiredRole } = paramsif (!requiredRole) {
return next()
}const [, , context, definition] = args
const { role } = contextif (!role.includes(requiredRole)) {
if (definition.returnType instanceof GraphQLList) return []
throw new Error('Unauthorized')
}return next()
},
)
```3. bind your directives implementation to your schema
```js
import { makeExecutableSchema } from 'graphql-tools'
import typeDefs from './types'
import auth from './auth'export default () => {
const resolvers = {
Query: {
users: () => [
{
id: 'fabien-juif-1',
fullName: 'Fabien JUIF',
},
],
},
}return makeExecutableSchema({
typeDefs,
resolvers,
schemaDirectives: {
auth,
},
})
}
```4. use your directives
```js
import { gql } from 'apollo-server'
import user from './user'export default gql`
${user}type Query {
users: [User] @auth(requires: ADMIN)
}
`
```