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 🙏

© 2025 – Pkg Stats / Ryan Hefner

apollo-link-json-api

v0.1.2

Published

Query JSON API compliant services with GraphQL

Readme

JSON API Link Build Status codecov

Purpose

An Apollo Link to easily use GraphQL with a JSON API compliant server.

Built on top of apollo-link-rest. If you have a non-JSON API REST service, check that out as an alternative.

Installation

npm install apollo-link-json-api apollo-link graphql graphql-anywhere qs humps --save

# or

yarn add apollo-link-json-api apollo-link graphql graphql-anywhere qs humps

apollo-link, graphql, qs, humps, and graphql-anywhere are peer dependencies needed by apollo-link-json-api.

Usage

Basics

import { JsonApiLink } from "apollo-link-json-api";
// Other necessary imports...

// Create a JsonApiLink for the JSON API
// If you are using multiple link types, jsonApiLink should go before httpLink,
// as httpLink will swallow any calls that should be routed through jsonApi!
const jsonApiLink = new JsonApiLink({
  uri: 'http://jsonapiplayground.reyesoft.com/v2/',
});

// Configure the ApolloClient with the default cache and JsonApiLink
const client = new ApolloClient({
  link: jsonApiLink,
  cache: new InMemoryCache(),
});

// A simple query to retrieve data about the first author
const query = gql`
  query firstAuthor {
    author @jsonapi(path: "authors/1") {
      name
    }
  }
`;

// Invoke the query and log the person's name
client.query({ query }).then(response => {
  console.log(response.data.name);
});

Advanced Querying

JSON API Link supports unpacking related resources into a friendlier GraphQL query structure.

const query = gql`
  query firstAuthor {
    author @jsonapi(path: "authors/1?include=series,series.books") {
      name
      series {
        title
        books {
          title
        }
      }
    }
  }
`;

While JSON API Link does support running multiple nested queries, prefer sideloading resources in a single request by using the ?include parameter if your JSON API server supports it.

// Avoid this
const badQuery = gql`
  query firstAuthor {
    author @jsonapi(path: "authors/1") {
      name
      series @jsonapi(path: "authors/1/series") {
        title
      }
    }
  }
`;

// Prefer this
const query = gql`
  query firstAuthor {
    author @jsonapi(path: "authors/1?include=series") {
      name
      series {
        title
      }
    }
  }
`;

Mutations

import React from 'react'
import gql from 'graphql-tag'
import { Mutation } from 'react-apollo'

export const UPDATE_BOOK_TITLE = gql`
  mutation UpdateBookTitle($input: UpdateBookTitleInput!) {
    book(input: $input) @jsonapi(path: "/books/{args.input.data.id}", method: "PATCH") {
      title
    }
  }
`

const UpdateBookTitleButton = ({ bookId }) => (
  <Mutation
    mutation={UPDATE_BOOK_TITLE}
    update={(store, { data: { book } }) => {
      // Update your Apollo cache with result
      console.log(book.title)
    }}
  >
    {mutate => (
      <button onClick={() => 
        mutate({
          variables: {
            input: {
              data: {
                id: bookId,
                type: 'books',
                attributes: { title: 'Changed title!' }
              }
            }
          },
          optimisticResponse: {
            book: {
              __typename: 'books',
              title: 'Changed title!'
            }
          }
        })
        }>
        Update your book title!
        </button>
    )}
  </Mutation>
)

Options

JSON API Link takes an object with some options on it to customize the behavior of the link. The options you can pass are outlined below:

  • uri: the URI key is a string endpoint (optional when endpoints provides a default)
  • endpoints: root endpoint (uri) to apply paths to or a map of endpoints
  • customFetch: a custom fetch to handle API calls
  • headers: an object representing values to be sent as headers on the request
  • credentials: a string representing the credentials policy you want for the fetch call
  • fieldNameNormalizer: function that takes the response field name and converts it into a GraphQL compliant name
  • fieldNameDenormalizer: function that takes the JavaScript object key name and converts it into a JSON API compliant name
  • typeNameNormalizer: function that takes the JSON API resource type and converts it to a GraphQL __typename.

Context

JSON API Link uses the headers field on the context to allow passing headers to the HTTP request. It also supports the credentials field for defining credentials policy.

  • headers: an object representing values to be sent as headers on the request
  • credentials: a string representing the credentials policy you want for the fetch call

Accessing metadata and links

By default, this library flattens your server response. If you need to access values that are unavailable by this simple querying method, you can add includeJsonapi: true to your @jsonapi directive, which will instead return the flattened "GraphQL-like" structure under a graphql key, and the original response structure under a jsonapi key. Resources are still nested in a tree structure under the jsonapi key, but data/attribute/relatioship keys are not flattened out.

query authorsWithMeta {
  authors @jsonapi(path: "authors?include=series", includeJsonapi: true) {
    graphql {
      name
      series {
        title
      }
    }

    jsonapi {
      meta {
        pageCount
      }
      links {
        first
        last
        current
      }
      // The resource data is available here, though it's probably easier to
      // grab from the `graphql` structure
      data {
        attributes {
          name
        }
        relationships {
          series {
            data {
              attributes {
                title
              }
            }
            links {
              related
            }
          }
        }
      }
    }
  }
}

Contributing

This project uses TypeScript to bring static types to JavaScript and uses Jest for testing. To get started, clone the repo and run the following commands:

npm install # or `yarn`

npm test # or `yarn test` to run tests
npm test -- --watch # run tests in watch mode

npm run check-types # or `yarn check-types` to check TypeScript types

To run the library locally in another project, you can do the following:

npm link

# in the project you want to run this in
npm link apollo-link-json-api