npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

graphql-bridge

v1.1.0

Published

A package to easily integrate services/apis with your GraphQL resolvers

Downloads

27

Readme

GraphQL Bridge

With the classes provided by this repository you can easily integrate multiple REST and GraphQL endpoints in a uniform way.

This is especially useful when your application uses more than one API (for example Twitter and GitHub at the same time). Since most GraphQL documentation only describes how to wrap one single REST API I wrote this library to fix inconsistencies in using different services.

Usage

Basics

The two classes provided serve as base to inherit from. For each API to use in your application you should create sub class of the respective class of the library. A integration for an REST API needs to inherit from GraphQLRestBridge, a integration of an GraphQL API, you guessed it, from GraphQLBridge.

A simple example for the integration of the Google Maps GeoCoding API to reverse GeoCode an arbitrary address is shown below:

import { GraphQlRestBridge } from 'graphql-bridge';

export default class GraphQLGeoCodingRestBridge extends GraphQlRestBridge {
  constructor() {
    super({ key: 'ABC123' });
  }
  async reverseGeocode(address) {
    const result = await super.request({
      endpoint: 'https://maps.googleapis.com/maps/api/geocode/json',
      data: {
        address,
      },
    });
    return result;
  }
}

Using the constructor you can provide data (and headers) that should be included in every request.

/*
 * Provides simple way to request data from an REST Endpoint
 *
 * @param {Object} defaultData What to include in every request
 * @param {Object} defaultHeaders What headers to include in every request
 */
 constructor(defaultData = {}, defaultHeaders = {}) {...}

It is important to note, that GraphQL subclasses will work in exactly the same way, as shown below:

export default class GraphQLGitHubBridge extends GraphQlBridge {
  constructor() {
    super(
      'https://api.github.com/graphql',
      {},
      { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` }
    );
  }
  async getUser(name) {
    const result = await this.request({
      query: `
        query {
            user(login: "${name}") {
                email,
                name,
            }
        }
    `,
    });
    return result;
  }
}

As a small difference, the first argument in the constructor is the URL of the API.

The actual usage of the library is illustrated in my repository GraphQL-Bridge-Demo (https://github.com/simonvomeyser/graphql-bridge-demo) where I integrated Twitter, GitHub and GoogleMaps.

super.request

This is the only function provided by both classes of the library and is used to make the actual request to the server. The possible arguments are as follows:

| Argument | RESTBridge | GraphQLBridge | Description | | -------- | ---------- | ------------- | ----------------------------------------------------------------------------------- | | endpoint | ✅ | ❌ | The enpoint to call an retrieve the data from. String | | method | ✅ | ❌ | Wrapper around the axios library, get,post,patch,put,delete. get is default. String | | data | ✅ | ❌ | The data to include in the requests body. Object | | query | ❌ | ✅ | The actual GraphQL query or mutation. String | | headers | ✅ | ✅ | The headers to include in the requests. Object | | nester | ✅ | ✅ | Nester function | | mapper | ✅ | ✅ | Mapper function | | filter | ✅ | ✅ | Filter function |

Nester

One of the three functions that can be passed to the super.request() function. Use to extract nested data. An simple example is shown below:

data => data.deep.nested.object.prop;

Filter

Offers the possibility to implement authorization or simple rules under which conditions data should be returned or not. Should return true or false. The example makes finding PersonX impossible.

user => {
  if (user.name === 'PersonX') return false;
  return true;
};

Mapper

Maps data from the service to own data so it can be used with GraphQL types. The example below shows mapping the returned data from the GoogleMaps API to an own GraphQL Type.

data => {
  data.addressName = data.formatted_address;
  data.lat = data.geometry.location.lat;
  data.lng = data.geometry.location.lng;
  return data;
};

Inside of a Resolver

After preparing an integration as described the created classes can simply be used inside of a Resolver to greatly simplify interacting with services. The variable GoogleGeoCodeIntegration is an instance of the class we created above.

  geoCodedLocation: {
    type: GoogleGeoCodeType,
    resolve(parentValue) {
      return GoogleGeoCodeIntegration.reverseGeocode(parentValue.location);
    },
  },