Although today was a workday, I spent it in blissful exploration on a technology we’re going to be using in our application: GraphQL.
- Rails application, running 4.2.8
- Webpack 2x, upgraded in existing the
- React client without any sprockets support
I set up a toy application based on the above constraints, at graphql_sample to practice and dig into learning how GraphQL works.
A little intro, although it’s best to head over to the main GraphQL website if you want to know more about it.
GraphQL is a new sort of query language for APIs that gives your client applications a very different experience of data than the familiar RESTful APIs. It’s centered around data objects in a way that’s both similar to JSON-API, but still quite different form that.
It’s a descriptive (declarative) language, where you define your data’s types, fields, functions, queries, and schemas.
Let’s look at an example. Supposed you had a data model that looked something like this, from ActiveRecord in Rails:
An example of a GraphQL type that describes a post looks like:
Based on that Post type, you can construct a Query that retrieves posts:
(Indeed, queries are also types.)
The schema is the top level part of the whole bit that brings the data types and query types together, and forms the API itself.
Mutations are the flip-side of queries, where you can create, update, and remove data, i.e. “mutate” it. I didn’t get that far at all today.
Apollo client is a client that implements the GraphQL client-side of the API really well. They have dev kits for React, Angular, IOS, Android, and even Vanilla JS. Since my interest right now is in React, I delved into the Apollo React Client (Note that this works with both web and native react.)
The morning was spent with the first two tutorials, building out the React Apollo client and an Express GraphQL server. They were great tutorials, and went smoothly.
My version, based on the tutorial, is over at graphql-tutorial
This was enough to get me chomping at the bit to do it in Rails.
A while back, I did write a pretty simple GraphQL Rails API using both
graphql-api gems. The latter makes the
implementation pretty easy based on introspecting the apps models, but
I wasn’t quite sure it’s ready for prime-time yet.
Today, I started over, creating a server app within the constraints
listed above, and added the
graphql gems. The
interesting thing is that installing the
graphql in rails loaded up
further gems, including a GraphiQL interface that let’s you
introspect the API while in development.
There was a lot of back-and-forth with
webpack-rails. In the end, I
probably should have just configured the thing directly with webpack
2x and all the needful.
I did try going the
create-react-app way at first, and ended up
keeping a lot of it after ejecting the build, but finally relying on
my own understands of webpack configuration and knowing the current
way our application works to be the final arbiters.
pretty interesting, in that it sets up a route for the GraphQL API
/graphql, which is somewhat of a default / convention. It
mounts the GraphiQL engine on
/graphiql at the same time, which is a
nice way to work, as you can progressively test out your types,
queries, and schemas as you work.
The gem creates a new folder under
app/graphql/ with a default
schema and query type. Types are under the
directory, and so get name-spaced
Type::NameType. The DSL
(domain-specific language) used to define things is quite similar to
the GraphQL syntax, although of course fit to Ruby.
For example, the default query created looks like this:
Here’s where the real learning and experimenting started. Up to now, things have been pretty simple and straight-forward.
I created the Post model described above, populated it with a few entries.
I wrote the following as the data type for the Post model:
Then modified the sample query to produce a query that would find a post by it’s ID:
Without changing anything else, I was able to successfully query the API to get a post.
But, how do I get multiple Posts?
Here’s where I spent the last two hours or so of the day, trying to figure out how this works. Clearly, it’s possible, and I think I have some ideas to go forward, but I was really stuck at this point.
This looks like it might provide some insight when I work on this next.
The concept is also explored in Jake Trent’s blog
return an array in graphql
although I’ll still need to translate to
All-in-all, a productive, happy day learning something completely new. Frustrations go along with learning; as one of my teachers says “That banging your head on the desk, that’s called growth” (Hi, Scott!)