Skip to content

graphql-community/graphql-directive-rest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

graphql-directive-rest

Version downloads PRs Welcome MIT License

Introduction

GraphQL is often used to integrate applications with REST API. Using this directive allows you to make REST integrations without creating any resolvers 🎉 😮

Table of Contents

Installation

yarn add graphql-directive-rest

This package requires graphql and graphql-tools as peer dependency

Usage

Standard approach, without the @rest directive

const { makeExecutableSchema } = require('graphql-tools');
const restDirective = require('../index');
const fetch = require('node-fetch');

const typeDefs = `
  type User {
    login: String
    avatar_url: String
  }

  type Me {
    gender: String
    email: String
    admin: String 
  }

  type Query {
    me(gender: String): Me
    users: [User]
    user(user: String): User
  }
`;

const resolvers = {
  Query: {
    me: (_, args) =>
      fetch(`https://randomuser.me/api/?gender=${args.gender}`)
        .then(res => res.json())
        .then(data => data.results[0]),
    users: () => fetch('https://api.github.com/users').then(res => res.json()),
    user: (_, args) =>
      fetch(`https://api.github.com/users/${args.user}`).then(res =>
        res.json()
      ),
  },
  Me: {
    admin: () =>
      fetch('https://yesno.wtf/api')
        .then(res => res.json())
        .then(data => data.answer),
  },
};

module.exports = makeExecutableSchema({
  typeDefs,
  resolvers,
  schemaDirectives: {
    rest: restDirective,
  },
});

Using @rest directive

When using @rest directive, we don't need to write any resolvers 🎉

const { makeExecutableSchema } = require('graphql-tools');
const restDirective = require('../index');

const GITHUB_URL = 'https://api.github.com';
const USER_URL = 'https://randomuser.me/api';
const ADMIN_URL = 'https://yesno.wtf/api';

const typeDefs = `
  type User {
    login: String
    avatar_url: String
  }

  type Me {
    gender: String
    email: String
    admin: String @rest(url: "${ADMIN_URL}" extractFromResponse: "answer")
  }

  type Query {
    me(gender: String): Me @rest(url: "${USER_URL}/?gender=$gender" extractFromResponse: "results[0]")
    users: [User] @rest(url: "${GITHUB_URL}/users")
    user(user: String): User @rest(url: "${GITHUB_URL}/users/$user")
  }
`;

module.exports = makeExecutableSchema({
  typeDefs,
  schemaDirectives: {
    rest: restDirective,
  },
});

Warning! Directive overwrites your resolvers if they're defined

Example queries:

query {
  users {
    login
    avatar_url
  }
}
query($user: String) {
  user(user: $user) {
    login
    avatar_url
  }
}
query($gender: String) {
  me(gender: $gender) {
    gender
    email
    admin
  }
}

Directive Parameters

Directive params:

url: String required

Endpoint from where we want to get the data.

extractFromResponse: String

The path where is the data that we want to get.

Response:

{
  "results": [
    {
      "gender": "male",
      "name": {
        "title": "mr",
        "first": "Elon",
        "last": "ons"
      }
    }
  ]
}

Examples of usage extractFromResponse

To get the title: "results[0].name.title" or to get the gender: "results[0].gender"

Contributing

I would love to see your contribution. ❤️

For local development (and testing), all you have to do is to run yarn and then yarn dev. This will start the Apollo server and you are ready to contribute 🎉

Run yarn test (try --watch flag) for unit tests (we are using Jest)

LICENSE

The MIT License (MIT) 2018 - Luke Czyszczonik - mailto:lukasz.czyszczonik@gmail.com