Catalog npm
Back to packageRELEASE DETAILS

1.0.0

npm

0xql

Easily add GraphQL support to any 0x Relayer that follows the [0x Standard Relayer API](https://github.com/0xProject/standard-relayer-api) spec.

Published11 Sept 2019
Direct dependencies31
Transitive dependenciesNot calculated

README

Current package documentation

0xQL (ZeroEx GraphQL)

Easily add GraphQL support to any 0x Relayer that follows the 0x Standard Relayer API spec.

Demo

Check out the GraphiQL playground here. Try creating some queries, mutations, or subscriptions.

Check out the getting started guide for a sample query and sample subscription to try out on the demo playground.

Overview

0xQL enables developers to quickly build a GraphQL server that can automatically integrate with an existing 0x Relayer. The GraphQL server mirrors functionality of the 0x Relayer's REST and WS API, but instead can be accessed via GraphQL's Queries, Mutations, and Subscriptions.

Getting Started

Prerequisite

  • >= Node v10
  • >= Yarn v1.5

Installation

yarn add 0xql

Quick Start Guide

This guide will walk through setting up a 0xQL GraphQL server that works with RadarRelay.

Install the dependencies

$ yarn add 0xql apollo-server

Create an index.js file

$ touch index.js

Add the following code to index.js

// index.js
const { ApolloServer } = require('apollo-server')
const { createReadyToUseResolvers, typeDefs } = require('0xql')

const APP_PORT = 4000
const REST_API_ENDPOINT = 'https://api.radarrelay.com/0x/v2'

const {
  queryResolver,
  mutationResolver,
  jsonResolver,
} = createReadyToUseResolvers(REST_API_ENDPOINT)

const resolvers = {
  Query: queryResolver,
  Mutation: mutationResolver,
  JSON: jsonResolver,
}

const server = new ApolloServer({
  typeDefs,
  resolvers,
})

// Start the GraphQL server
server.listen({ port: APP_PORT }, () =>
  console.log(
    `🚀 Server ready at http://localhost:${APP_PORT}${server.graphqlPath}`
  )
)

Finally, start the server

node index.js

If everything worked, you should see the following printed in the console

🚀 Server ready at http://localhost:4000/

Congrats, you have your own functional 0xQL GraphQL instance pointed at RadarRelay. Let's try it out!

Navigate to http://localhost:4000 to check out the GQL playground

Try a sample query:

query GetOrders {
  orders {
    records {
      order {
        makerAssetData
        makerAssetAmount
        takerAssetData
        takerAssetAmount
      }
    }
    total
    page
    perPage
  }
}

Adding Subscriptions

In addition to fetching data using queries and modifying data using mutations, the GraphQL spec supports a third operation type, called subscription. GraphQL subscriptions are a way to push data from the server to the clients that choose to listen to real time messages from the server.

If you're looking to add subscriptions, check out the implementation example here which builds on the server we just made.

Subscriptions Demo

Check out the demo site for a live demo.

Here's a sample subscription to send to the GraphQL server:

subscription SubscribeToAllOrders {
  subscribeToOrders(type: subscribe, channel: orders, requestId: "1234") {
    payload {
      order {
        makerAddress
        makerAssetData
        takerAddress
        makerAssetAmount
        takerAssetData
        takerAssetAmount
        signature
        expirationTimeSeconds
      }
    }
  }
}

You'll start to get a stream of incoming orders that look like the structure you just requested:

{
  "data": {
    "subscribeToOrders": {
      "payload": [
        {
          "order": {
            "makerAddress": "0x50f84bbee6fb250d6f49e854fa280445369d64d9",
            "makerAssetData": "0xf47261b00000000000000000000000000f5d2fb29fb7d3cfee444a200298f468908cc942",
            "takerAddress": "0x0000000000000000000000000000000000000000",
            "makerAssetAmount": "35003789556299530000000",
            "takerAssetData": "0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
            "takerAssetAmount": "6609708813064056613",
            "signature": "0x1b37b290a52a5afccf8c9eb155b37dad510aad8b37a607b939ef6c72b73bc86d956d53dd6bc8c910d8f0d28f6fa94b567151a24dedd3d83404eea67684e348481003",
            "expirationTimeSeconds": "1568183099"
          }
        }
      ]
    }
  }
}

More examples

  • Basic (without subscriptions)
  • Basic (with subscriptions)
  • Advanced (demos integration with existing express server)

Client Side Integration

Here's an example of integrating React and React Hooks with the 0xQL server. This assumes a React app already exists (you can always use create-react-app to bootstrap your app).

We're going to use the popular GraphQL library Apollo which offers smooth integration with React. Apollo offers a set of React Hooks which we can consume directly inside our components.

First, set up the code, which includes importing the required code and setting up your first query.

yarn add apollo-boost @apollo/react-hooks graphql
import gql from 'graphql-tag'
import { useQuery } from '@apollo/react-hooks'

const GET_ORDERS_SUMMARY = gql`
  {
    orders {
      records {
        order {
          makerAssetData
          makerAssetAmount
          takerAssetData
          takerAssetAmount
        }
      }
      total
      page
      perPage
    }
  }
`

Now let's write our React component

function Orders({ onOrderSelected }) {
  const { loading, error, data } = useQuery(GET_ORDERS_SUMMARY);

  if (loading) return 'Loading...';
  if (error) return `Error! ${error.message}`;

  return (
    <div>
      {data.orders.records.map(order) => (
        <div onClick={() => onOrderSelected && onOrderSelected(order)}>
          {order.makerAssetData}
        </div>
      )}
    </div>
  );
}

Then finally, let's wrap the component in an App and a GraphQL provider:

import React from 'react'
import ApolloClient from 'apollo-boost'
import { render } from 'react-dom'
import { ApolloProvider } from '@apollo/react-hooks'

const client = new ApolloClient({ uri: 'http://localhost:4000' })

const App = () => (
  <ApolloProvider client={client}>
    <Orders onOrderSelected={order => console.log('order selected', order)} />
  </ApolloProvider>
)

render(<App />, document.getElementById('root'))

That's it!

API

Available Imports

  • typeDefs
  • createReadyToUseResolvers
  • resolvers

typeDefs - This is the Type Definitions for the GraphQL schema

createReadyToUseResolvers - A factory function to create opinionated, ready-to-use resolvers, and if requested, sets up websockets automatically.

interface SubscriptionConfiguration {
  autoSubscribe?: boolean
  websocketUrl?: string
  ordersTopic?: string
  pubsub?: PubSub
}

const resolvers = createReadyToUseResolvers(
  relayerRestApiUrl: string,
  customSubscriptionConfig: SubscriptionConfiguration
):

Returns: Object that contains the following:

  • queryResolver
  • mutationResolver
  • subscriptionResolver
  • jsonResolver

See the basic example on the usage here.

resolvers: More advanced fine-grained, less opinionated configuration over resolvers than createReadyToUseResolvers provides. See the advanced example on usage.

FAQ

What's GraphQL?

GraphQL is a query language for APIs that enables declarative data fetching in order to give the client the power to specify exactly the data that is needed from the API.

What's 0x?

An open protocol for decentralized exchange on the Ethereum blockchain.

What's 0xQL

A package that provides primitives and tooling for building GraphQL support into your 0x Relayer.

How does this package apply to GraphQL?

This package, 0xQL, provides the necessary GraphQL bindings, resolvers, schema, and types. We also include an optional opinionated setup with most things preconfigured.

How does this package apply to 0x?

The 0x Standard Relayer API dictates a standard interface for both REST and WebSocket interaction for a relayer. Since this interface is standardized across relayers, we can also add support for GraphQL in a consistent and robust way. This package supports GraphQL queries, mutations, and subscriptions.

Sounds good, but how do I use this?

This package provides various ways to consume the 0xQL package, depending on your level of configuration required. For example, 0xQL supports:

  • Creating a standalone GraphQL server with minimal configuration. Check out the basic example here.

  • If you already have an express server and want to add GraphQL support, you can layer in GraphQL quite easily. Check out the advanced example here

  • If you already have a GraphQL API and you want to add 0x relayer support, you can take the 0xQL schema and types and stich it together with your own existing GraphQL schema. (See Apollo docs for guides on schema stiching and federated GraphQL support)

Why write this package?

Why not?

Having more ways and to interact and integrate with 0x relayers is a win for the ecosystem.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 31

Native requirements
31 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
0x.js
Environment
{
  "local_name": "0x.js",
  "alias": false,
  "peer_metadata": null
}
^7.0.1runtime
@0x/assert
Environment
{
  "local_name": "@0x/assert",
  "alias": false,
  "peer_metadata": null
}
^2.1.5runtime
@0x/connect
Environment
{
  "local_name": "@0x/connect",
  "alias": false,
  "peer_metadata": null
}
^5.0.18runtime
@0x/json-schemas
Environment
{
  "local_name": "@0x/json-schemas",
  "alias": false,
  "peer_metadata": null
}
^4.0.1runtime
@0x/order-utils
Environment
{
  "local_name": "@0x/order-utils",
  "alias": false,
  "peer_metadata": null
}
^8.3.1runtime
@0x/types
Environment
{
  "local_name": "@0x/types",
  "alias": false,
  "peer_metadata": null
}
^2.4.2runtime
apollo-link-ws
Environment
{
  "local_name": "apollo-link-ws",
  "alias": false,
  "peer_metadata": null
}
^1.0.18runtime
apollo-server
Environment
{
  "local_name": "apollo-server",
  "alias": false,
  "peer_metadata": null
}
^2.9.3runtime
graphql
Environment
{
  "local_name": "graphql",
  "alias": false,
  "peer_metadata": null
}
^14.5.4runtime
graphql-subscriptions
Environment
{
  "local_name": "graphql-subscriptions",
  "alias": false,
  "peer_metadata": null
}
^1.1.0runtime
graphql-tools
Environment
{
  "local_name": "graphql-tools",
  "alias": false,
  "peer_metadata": null
}
^4.0.5runtime
graphql-type-json
Environment
{
  "local_name": "graphql-type-json",
  "alias": false,
  "peer_metadata": null
}
^0.3.0runtime
lodash
Environment
{
  "local_name": "lodash",
  "alias": false,
  "peer_metadata": null
}
^4.17.15runtime
reconnecting-websocket
Environment
{
  "local_name": "reconnecting-websocket",
  "alias": false,
  "peer_metadata": null
}
^4.2.0runtime
subscriptions-transport-ws
Environment
{
  "local_name": "subscriptions-transport-ws",
  "alias": false,
  "peer_metadata": null
}
^0.9.16runtime
uuid
Environment
{
  "local_name": "uuid",
  "alias": false,
  "peer_metadata": null
}
^3.3.3runtime
web3
Environment
{
  "local_name": "web3",
  "alias": false,
  "peer_metadata": null
}
^1.2.1runtime
ws
Environment
{
  "local_name": "ws",
  "alias": false,
  "peer_metadata": null
}
^7.1.2runtime
@graphql-codegen/cli
Environment
{
  "local_name": "@graphql-codegen/cli",
  "alias": false,
  "peer_metadata": null
}
^1.7.0development
@graphql-codegen/introspection
Environment
{
  "local_name": "@graphql-codegen/introspection",
  "alias": false,
  "peer_metadata": null
}
1.7.0development
@graphql-codegen/typescript
Environment
{
  "local_name": "@graphql-codegen/typescript",
  "alias": false,
  "peer_metadata": null
}
1.7.0development
@graphql-codegen/typescript-resolvers
Environment
{
  "local_name": "@graphql-codegen/typescript-resolvers",
  "alias": false,
  "peer_metadata": null
}
1.7.0development
@types/graphql
Environment
{
  "local_name": "@types/graphql",
  "alias": false,
  "peer_metadata": null
}
^14.5.0development
@types/lodash
Environment
{
  "local_name": "@types/lodash",
  "alias": false,
  "peer_metadata": null
}
^4.14.138development
@types/uuid
Environment
{
  "local_name": "@types/uuid",
  "alias": false,
  "peer_metadata": null
}
^3.4.5development
@types/web3
Environment
{
  "local_name": "@types/web3",
  "alias": false,
  "peer_metadata": null
}
^1.0.19development
@types/ws
Environment
{
  "local_name": "@types/ws",
  "alias": false,
  "peer_metadata": null
}
^6.0.3development
apollo-server-express
Environment
{
  "local_name": "apollo-server-express",
  "alias": false,
  "peer_metadata": null
}
^2.9.3development
prettier
Environment
{
  "local_name": "prettier",
  "alias": false,
  "peer_metadata": null
}
^1.18.2development
ts-node
Environment
{
  "local_name": "ts-node",
  "alias": false,
  "peer_metadata": null
}
^8.3.0development
typescript
Environment
{
  "local_name": "typescript",
  "alias": false,
  "peer_metadata": null
}
^3.6.2development

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "shasum": "0ce8e792ff0b8b06b2f5e921a42cfca225813881",
  "integrity": "sha512-5DcjM89uD/aJhbC7/Jk/yqtASWTKtXcnTsp4qGoI5LiwIAsmxJOTwOyiRxw9MsUlMXpeE9uuoho0gQdi8x8Yyw==",
  "tarball": "https://registry.npmjs.org/0xql/-/0xql-1.0.0.tgz",
  "fileCount": 25,
  "unpackedSize": 107568,
  "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdeKmcCRA9TVsSAnZWagAAJRUP/R2kBvvCG8CgFZYxfuQ9\nh+xTMyfPpTu6KKu3EHVmdFRDWu3TfwIvjo9UYixZKrWn5jTeADTib2rdQ4Nv\njhS6ELQFr6WwImDOPVAdVHqywJebCcyTT7EbLT3rs7C66jHvb/4Lx5RTiqMM\nHlf+yDV4QKzV8zNZ4K9rvbI1r9hgWwox8fsrFwWyGEr+ocfS2No5nEtsqVKL\nvmMVpaA/APXEvaQxxX5x1y7XKU7xmMxnuGQknFUBXpb6o5mcRg5Ro8vgbCpD\nXfNEt5PSW8iDW0Kpgx18kY0s72Z/JSVWkPy5zg/5iB7GpFDWz6nThERgO8J/\nM9arhK+6vlIVUxm5ECV4mo74ilTEqpjjCM/ZwhM3mWpA0dBInTNoE4YehIGj\na/CwF1EJtGxhv1I/FfVSP3bRUUVWhGIbBp59qEKKuJ2po6P5WK9Aj+10MWPm\nog6sDOgWL6FsrWdCS8A27hKDQnZOqrF1i4digOEqiKAp5zT82hbzFcJlelvP\nwiECSXx0/Zm18lcoguyfuGIrZxxdWNaB/G7Peuds5+0Lf+Rwu0ck9Ttv6C0V\ng6wZYIC8NN6AKW7Zd7NHxTDJvABATlEenUsq1d55fgOpKBDcCisgPK0Y2zWz\nrs5plxs03xAqe3eZf4XuH50K/zCyxc8TkFp2ifHpTudiXGwrtSt5fuJf/LBI\neDx3\r\n=TeKr\r\n-----END PGP SIGNATURE-----\r\n",
  "signatures": [
    {
      "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
      "sig": "MEUCIG2oYSbTMPzjloIvDHyfXuFPCSyFemJT2EukjRQBIa5LAiEAuz+DsS5O4nGxdsj/73WJmDuEo+KFYAQRa/ln0m/98L0="
    }
  ]
}

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 17:52 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:ec90e328667ef4e411a61e0096c54e8f4cbd3263e1feb81d3c9e56d286e249f7

Other collected versions

0.0.110 SeptView all collected versions →