Monday, 12 November 2018

GraphQL, middleware and Mule

I'm not sold on GraphQL and this post is not going to go into detail about GraphQl or anything. This is a just small post to show how middleware and GraphQL specifically Mule in this case play quite well together.

GraphQL and it's adovcates touts how it can fetch multiple respurces together and choreggraph and combine data from Rest APIs, databases, SOAP services etc. Sound familiar, it sounds like most middleware tools. But that's not what GraphQL does. It gives you the API layer to be able to do that, but not actually the middleware part to orchestrate and connect all the systems.

Basically it gives you the API layer and then the technology implementation of it such as GraphQL-java gives you a concept of 'resolvers'. These resolvers you then need to code how to get your data for the specific fields requests in the graphql request.

Although in it's infancy, it just a lab project atm. Mulesoft has a minimal GraphQL router module that works quite nicely. Here is an example of a simple GraphQL schema we will use to demonstrate:

A sample GraphIQL request:

And here is response received from Mule:

And here is the mule config to implement the API:

Basically the module allows you define flows for every field. It will route to the flow containing a field resolver matching the name of the field in the request. In the example we have requested: author, name and book, name

You can define a field resolver for each of these fields if you wanted to. But as we typically will get the name for the author from one source and the name of the book from one source, a resolver for author and books is enough. As there are no field resolvers specifically defined for 'name' in either case, the router will automatically select them from the payload returned in the flow as the default resolver. So in the author and books flow, both need to have a field called 'name' in the payload in order to return the value.

As I said the module is in it's infancy and needs some work to add the proper attributes to the message for the fields requested and the query parameters for example. But they are available as you can see in the mule config example. In the request, we request authors with name="ryan" that query parameter is available via attributes.getArguments(). The requested fields to return are handy so we can modify our SQL queries to prevent over-fetching for example, they are available via attributes.getSelectionSet()

As a graph is a hierarchical, the router will execute each flow in order from top-down. So the response from the author flow will be the payload sent to the books flow for example. So at the moment you have to make sure to copy and pass the correct arguments around that you need in each flow to fetch your data.

Also, as you can see there is a simple static resource hosted also to provide the GraphIQL console for interacting and testing with the API. The full working project is on my Github here

Anyway, it's a promising module and will hopefully get the same attention as the APIKit router to make it more friendly. I'm working on some improvements myself for it.

1 comment: