Converting Stripes API to GraphQL
Note: GraphQL is used for read queries only, writes are still done directly with the REST API.
Stripe currently uses an HTTP REST interface for it's API. If you use the Chrome dev tools to look at the network requests whilst using the Stripe admin UI, you can see that internally they are using GraphQL.
I do not think they will offer a public GraphQL interface in the near future, because it will multiply their external surface area without much benefit. They are still using HTTP 1.1, probably for the same reason.
What is GraphQL?
GraphQL contains two languages:
-
- A type system to define types.
- AKA IDL: Interface Definiton Langauge.
- This is like C# or Java with only the type definitions (no functions).
-
- A query language which references the types.
The server knows about 1 (types). Clients produce 2 (queries).
When the server receives a query, it checks it is valid (syntax and types). The server computes the result, and returns JSON to the client.
GraphQL benefits compared to REST
There are some good reasons GraphQL is being chosen over REST:
-
A GQL server can run any query.
- The client can produce any query dynamically at runtime.
- New queries do not require server side changes.
- The GQL server remote-executes any query the client gives it, but the "query to server" code generation is safe.
- This enables front end developers to Just-In-Time™ create their queries at the same time they are creating the UI that consumes the result set.
- This is faster than having to context switch to backend code and create a new URL endpoint (or request the new endpoint from the backend team).
-
GQL types are a specification.
-
Many REST server implementations do not have a specification - a specification would allow you to machine check some artifact to definitively say "Artifact X matches Specification Z".
- The spec for most server implementations are "what ever the server actually does". This is bad as there is no right or wrong answer (Not Even Wrong).
- This means you cannot auto generate documentation describing the API, or replace the server implementation with a functionally equivalent one.
- The Web SQL API was removed for a similar reason - there is no definitive specification for the existing SQLite code base, even though it has proven utility in practise.
- The spec for most server implementations are "what ever the server actually does". This is bad as there is no right or wrong answer (Not Even Wrong).
-
GQL forces you to specify types.
- If a developer knows the types, they can create valid queries and/or replace the server implementation with a functionally equivalent one.
- Queries and security not specified: Queries are still completely general (any query allowed, but it must be syntactically valid), and your security logic will have to be layered over the types in a non-GQL language.
-
Reasons against GQL (compared to REST):
-
Requires extra dependencies.
- Most server languages have HTTP server implementations in their standard libraries. You can implement your server with only the standard libraries of the language.
- GQL will use these HTTP libraries too, but you will always have to depend on at least the GQL type and query parsers.
-
Less tooling support.
- HTTP is old and battle tested (Lindy effect).
- It has a huge ecosystem of tools that just work.
- GQL works over HTTP, but tools are not expecting GQL query syntax.
-
Uncertain runtime performance.
- A GQL server will typically use a library that auto converts a GQL query to SQL. This kind of auto-translation is a complex dependency to replace.
- It can be harder to profile and tune SQL queries that are automatically generated.
- With REST, you are typically directly writing the SQL, so have a better idea of how to optimize it. The SQL queries are viewable from your source code (instead of generated at runtime).
-
Harder to get Access Control logic correct.
- With REST, you have endpoints that have very clear access control logic.
- With GQL queries, you have to assign security logic to specific types (too fine-grained), or create a server side query whitelist to ban any queries that are not approved (and prevent malicious actors creating new queries to access data they should not).
Converting Stripes HTTP API to GraphQL
The tdog
CLI continuously downloads from your Stripe account and writes to your Postgres database.
Download your Stripe data to a Postgres database with the tdog
CLI.
You can wrap this Postgres database with a GraphQL server so that you can use GraphQL queries from the client.
The client could be a signed-in customers billing summary, or an admin interface where you join with your other GraphQL based business data (Hasura allows merging GQL schemas and using multiple databases).
Two tools that do this are:
-
- 10k GitHub stars.
- Node.js based.
npm install -g postgraphile
postgraphile -c postgres:///mydb -s public -a -j
-
- 22k GitHub stars.
- Server is written in Haskell.
- Start with docker-compose
- Hasura Cloud is a fully managed GraphQL server.
Related
-
Datasette + tdog = 99% cheaper Sigma
- Use Datasette which comes bundled with a GraphQL API.
-
IBM Open API to GraphQL.
- https://github.com/IBM/openapi-to-graphql
- Research paper: https://arxiv.org/abs/1809.08319
- This:
- A. Converts a REST Open API schema to a GraphQL schema.
- B. Converts GraphQL queries into the corresponding REST API calls.
- Issue: This does not allow you to leverage GQL benefits because it just makes REST API calls to compute a result.
- GQL benefits:
- Multiple table joins ("graph traversal").
- Select only the columns you need.
- Complex WHERE filtering/logic.
- The
tdog
solution above maintains the above GQL benefits because the underlyingresolve
functions are using the Postgres SQL engine that has native support for them.
- GQL benefits:
- https://github.com/IBM/openapi-to-graphql
-
Lamport: Who Builds a House Without Drawing Blueprints?
- GQL types are a kind of specification.
-
https://hasura.io/learn/graphql/intro-graphql/graphql-vs-rest/