Graphiti: Stylish Graph APIs
graphiti.dev
graphiti.dev
As important as a GraphQL alternative is at face value, he explained quite elegantly how he and his coworkers came to this solution. I do insist, like I did in person, that as a frustrated GraphQL noobie and fumbler with Prisma, I'm super glad to see alternative tools and mindsets and will being try it as soon as I have time for personal tinkering.
Even if hypothetically I didn't choose this with a clean slate over more popular GraphQL tools, he did a great job at placing deep technical architecture choices in the context of his philosophy and experience, Ruby and otherwise. Spraypaint also seems cool.
A pleasure to see you on HN, man.
Putting one sentence of what Graphiti is on the actual homepage would help adoption enormously. "Graphiti makes RESTful Resources a first-class concept" doesn't count as an explanation of what Graphiti is. "This enables reading and writing a graph of data in a single request, a schema with backwards-compatible gaurantee, end-to-end integration test patterns, seamless microservices and much more" might be a great explanation for the developer who wrote Graphiti but doesn't ease me as a first time visitor to the site into a comfortable understanding of whether Graphiti will solve my problem.
https://en.wikipedia.org/wiki/Curse_of_knowledge
It's truly astounding how universal this problem has become in tech.
My understanding looking at the query examples, https://www.graphiti.dev/quickstart#querying
It looks more like an ORM querying over rest than it is graphQL. It doesn't appear to solve some or the 2 major headaches graphQL is great at solving: * clients choosing how much data they need. On a desktop on broadband client, I want details of a list of entities, while on a mobile app with limited screen space and less bandwidth, I just need the skinny details like title and summary. * pooling requests to multiple domains into a single request. For example, if I writing a reservations endpoint, for purchasing flights. I need to call 3 separate microservices, 1 for availability and booking, 1 for ecommerce that's hooked up to an accounting system, and one for trip details from say a CMS system. I don't see how this saves the client the burden of making all these separate requests. In rest, you probably will have 1 endpoint that combines these requests, and separate endpoints for accessing this information individually. GraphQL saves the burden of maintaining separate combination endpoints.
The "Why Graphiti" page[1] goes into some of this, getting into some comparisons of REST, RPC, and GraphQL, as well as discussing the conventions that make some of Graphiti's approach possible.
Disclosure: I'm the other author of Graphiti
In my reservations example, if I wanted to get availability, pricing, and content from 3 separate domains in a microservice environment, using this paradigm, I think I still would have to create a 4th endpoint that that combines the 3 in a separate entity called VacationPackages if I wanted to keep separation of concerns.
Otherwise, it might be calling a CMS endpoint, which has an include of availability endpoint, which has a nested include of the pricing endpoint.
JSON:API solves this problem through sparse fieldsets[1]. Graphiti clarifies the spec by allowing sparse fieldsets at any level of nesting. As the original author and a current editor of the spec, I think we should adopt this extension into the spec proper.
> * pooling requests to multiple domains into a single request
JSON:API operates against a logical "graph in the sky", just like GraphQL. Graphiti makes it possible to mix and match database queries with other services and even plain Ruby objects[2].
One nice thing about this approach is that you still get to make database queries that take advantage of indexes and other database optimizations organically and by default. GraphQL's field-based approach can often result in a lot of extraneous database queries in the service of a homogenous server API that is based on fields.
(In my experience working with GraphQL APIs, I've seen a lot of performance issues that could only be debugged as "why is this field slow" that could have benefited a lot from making a big chunk of the query against a SQL database, directly using decades of optimizations around query planning).
[1]: https://jsonapi.org/format/#fetching-sparse-fieldsets [2]: https://www.graphiti.dev/cookbooks/without-activerecord
I like the more succinct schemas.
I like that it's simpler and easier to reason about than GraphQL.
I like the elegant solutions for lazy vs eager loading and supporting separate endpoints.
I like the sensible defaults for filtering and sorting based on type.
This is a very well thought out project, good job. Will it be the Next Big Thing? I'm not gonna make a call either way, but I'm glad that this exists and at the very least is worth investigating when building a new project.
If you have a toy project, than try Graphiti. If you're solving real-world problems; stick with GraphQL.
Fighting with the DSL, I mean cryptic errors, no instance variables to work with, and no straight forward way to extend the framework. I know it is possible to extend the framework, but it’s not very intuitive.
Graphiti uses JSON:API[1] under the hood as its protocol, which is a language-independent protocol with a wide variety of clients[2], and is now built-in to Drupal[3].
I designed JSON:API in ~ 2013 with a narrow purpose: to describe a protocol for incrementally communicating with server-side graphs over HTTP.
By incremental, I mean the possibility of fetching exactly the data you need at first, but then slowly filling in more data over time as a user interacts with an application.
URLs are a great "internet pointer", so when I was looking for a way to link fetched data with other not-yet-fetched data, URLs were the natural answer. On the other hand, a lot of REST APIs at the time didn't have a good way to eagerly send a whole bunch of graphy data down at once.
JSON:API's concept of linkage supports both models: a type/id pair for data the client already knows about and a URL for data it doesn't. You can even combine the two, to enable incremental refreshing of a piece of data that you fetched as part of the first request (simply by hitting the URL).
JSON:API was designed to work well with many kinds of client-side approaches, including ORMs. This meant using a composite key of type/id to identify records and not just a single ID. Over time, this has become a best practice for other tools in the space[4][5]
OData exists in a similar space as JSON:API, but JSON:API is much more tightly focused on the problem of incrementally fetching a graph of data from the server into the client. Focus is good :)
[1]: https://jsonapi.org/ [2]: https://jsonapi.org/implementations/ [3]: https://www.drupal.org/project/jsonapi [4]: https://graphql.org/learn/queries/ [5]: https://levelup.gitconnected.com/basics-of-caching-data-in-g...