Open albrow opened 4 years ago
I'd like to suggest to keep the JSON-RPC API.
The only thing JSON-RPC is missing is some tooling to fill the gap with GraphQL, thats exactly what OpenRPC is:
heres a live example running the playground/inspector against ethereum:
https://playground.open-rpc.org/?url=https://services.jade.builders/core-geth/ethereum/1.11.2
@shanejonas thanks for sharing your thoughts! Would you mind sharing a little background info about your role/company and experience with Mesh so far?
Couple quick questions about OpenRPC:
0x Mesh GraphQL API Specification
This is a proposal for a new GraphQL API for Mesh which will replace the existing JSON-RPC API in Mesh version 10.0.0. The JSON-RPC API will be removed in Mesh v10 and users who upgrade to v10 will need to use the new GraphQL API.
Background and Motivation
There are several motivating factors for why we are introducing a new API:
Improve Queryability of Mesh
Currently, Mesh does not offer much in the way of querying or filtering orders in its JSON-RPC API. Part of the reason for this is that JSON-RPC does not lend itself well to complicated queries.
Because of this, if you need to query orders, you will need to follow a somewhat complicated process for syncing Mesh with your own database and then running queries from there. Practically speaking, there is no other way to get only the orders you care about and make sure they are up-to-date. This can create an unnecessary burden for developers, especially in the browser where there are limited database options.
The new API will make it possible for many use cases to avoid syncing with their own database entirely. Instead, Mesh can be thought of as the database for orders. For example, you can query Mesh directly to get all ETH-DAI orders that expire no sooner than 60 seconds from now while filtering out dust orders.
Some users may still wish to sync their database (for example, if they want to do SQL joins with application-specific data), but it is an option rather than a requirement. Even for users that do want to sync their own database, improved querying capabilities at the API layer can still make it easier to do so by filtering out orders you don't care about earlier on in the pipeline.
Unify and Simplify our Tooling
In the current 0x tech stack, there are many different APIs and libraries that effectively do the same thing: get a set of orders that can be filled by anyone.
@0x/mesh-browser
@0x/mesh-rpc-client
@0x/connect
@0x/orderbook
All of these APIs and tools work differently (sometimes in subtle ways) and generally one cannot be used as a drop in replacement for the other. Some of them are compatible with one another and others are not. For example,
@0x/orderbook
works with SRA or the Mesh JSON-RPC API but doesn't work when running Mesh in the browser.One of the goals for the new GraphQL API is to provide a single API for getting orders whether you are talking to 0x API, running your own Mesh node, or even running Mesh in the browser.
We are still in the process of planning the timeline for this transition. One thing that's clear is that SRA will not disappear right away. A lot of users and bots rely on SRA, so our goal is to keep it up and running for the near future, although it may be marked as deprecated. In addition, any endpoints in 0x API not related to SRA (e.g.
/swap
and/meta_transaction
) will be unaffected.Better Documentation and Support for More Languages
The documentation for the existing JSON-RPC API is hand-written and must be manually updated whenever we make changes. Writing clients for new languages is also a largely manual process. While JSON-RPC is a widely accepted standard, it is not as structured or type safe as something like GraphQL. Additionally, Mesh relies on the subscriptions feature of JSON-RPC 2.0 which is not universally supported by clients.
Why GraphQL?
GraphQL was selected as a standard for the new API based on several important characteristics:
Playground Environment
We have deployed a playground environment which you can use to familiarize yourself with the new API. It supports autocompletion, syntax highlighting, subscriptions, and inline documentation. You can access the playground at https://meshmock.spaceship.0x.org/. See the Example Queries section below for some queries to try.
Some caveats to keep in mind:
BigNumber
fields are sorted alphanumerically instead of numerically. This also affects the results from filters that depend on ordering such asGREATER
orLESS
. This will not be the case in the final production API.GraphQL Schema
Here is the proposed GraphQL schema in its entirety:
Example Queries
This section includes some example queries which you can copy and paste in the playground. Of course, you would typically write queries programmatically with a GraphQL client, not by manually writing them. This is just for illustrative purposes.
Getting a Specific Order
You can get the details for any order by its hash:
Querying and Filtering Orders
You can get all orders via the
orders
query. By default, it will return up to 20 orders at a time sorted by their hash.The
orders
query supports many different options. Here's an example of how to get orders with a minimumexpirationTimeSeconds
and minimumremainingFillableAssetAmount
. You can use this to exclude dust orders and orders which may expire too soon.Here's an example of sorting orders by the
remainingFillableAssetAmount
. You can combine any number of filters and sorts in anorders
query.Adding Orders
You can add orders using a
mutation
. Note that in the playground orders will not actually be added and will not show up in subsequent queries. Also in the playground every other order will be rejected in order to provide an example of what therejected
field in the response looks like.Subscribing to Order Events
You can subscribe to order events via a
subscription
. The playground will send a mock order event every second.Getting Stats
You can get some stats about your Mesh node via the
stats
query.Pagination
We recommend paginating through orders by using
filters
andlimit
. So for example, if you want to sort orders by their hash (which is the default), you first send a query without any filters:The orders in the response will be sorted by
hash
(which is the default). Look at the last order you received, which in this case has a hash of0x75d2b56b11f21235ec8faec8be9d081090678cf62f5c69fa118236d829424719
. Send the next request by using the last hash you received in a filter:This will return any orders with a hash greater than
0x75d2b56b11f21235ec8faec8be9d081090678cf62f5c69fa118236d829424719
. Repeat this process, changing thehash
each time, until there are no orders left.There may be orders added or removed while you are in the process of paginating. Following this method guarantees that:
Query Fragments
GraphQL requires you to specify all the fields that you want included in the response. However, you can use query fragments to avoid repeating the same fields over and over. Here's an example of a query fragment that includes all the fields of an order.
Future Improvements
The API described above is what we are planning to ship with Mesh version 10.0.0. Our goal is to ship with a minimally viable API that improves the experience of interacting with Mesh for common use cases. However, this will not be the final state of the API and we are planning to follow up with a few specific improvements. Because of the way GraphQL requires specifying the fields you want to receive in the response, we can add new fields (e.g. to the
OrderWithMetadata
type) without increasing payload sizes for users who don't need those fields. These improvements will be backwards compatible.price
field toOrderWithMetadata
. This will allow sorting orders by price or using a filter to only return orders with a certain price or better.OrderWithMetadata
. This could allow you to more easily e.g. only receive ERC20 orders or find all orders for a specific ERC721 contract address with any token ID. The variety of asset datas and the existence of the MultiAssetDataProxy make it challenging to structure the data in an efficient way and expose a querying interface that is easy to use. That said, it should be possible and we know this is something users have been asking for.orderEvents
subscription. The current subscription returns all order events, since it is much easier to support on the backend. It should be possible, though somewhat challenging, to allow filtering similar to theorders
query.If you have any other ideas for improvements or new features, let us know :smile: