DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. GraphQL, Middleware, and Mule

GraphQL, Middleware, and Mule

This post shows how middleware and GraphQL, specifically Mule, in this case, play quite well together.

Ryan Carter user avatar by
Ryan Carter
·
Nov. 14, 18 · Tutorial
Like (5)
Save
Tweet
Share
20.59K Views

Join the DZone community and get the full member experience.

Join For Free

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 advocates tout how it can fetch multiple resources together and choreograph 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 its infancy, it's just a lab project at the moment. 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:

schema {
query: Query
}

type Query{
author(
        name : String
    ): Author

}

# This is the simple description of a humble author
type Author {
#this is the name of the author.
name: String
books: [Book]
}

type Book {
name: String
}

A sample GraphIQL request:

{
  author(name: "ryan") {
    name
    books{
      name
    }
  }
}

Here is response received from Mule:

{
  "data": {
    "author": {
      "name": "ryan",
      "books": [
        {
          "name": "Getting Started with Mule Cloud Connect"
        }
      ]
    }
  }
}

Here is the Mule configuration to implement the API:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:core="http://www.mulesoft.org/schema/mule/core"
xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:graphql="http://www.mulesoft.org/schema/mule/graphql" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd 
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/graphql http://www.mulesoft.org/schema/mule/graphql/current/mule-graphql.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd">

<http:listener-config name="api-httpListenerConfig">
<http:listener-connection host="0.0.0.0"
port="8083" protocol="HTTP">
</http:listener-connection>
</http:listener-config>

<graphql:config name="graphql-config" configName="mygraphql"
schemaLocation="schema/schema.graphqls" />

<flow name="console">
<http:listener config-ref="api-httpListenerConfig" path="/graphiql" />
<parse-template location="index.html" doc:name="Parse Template" />
<set-payload value="#[payload]" mimeType="text/html" />
</flow>

<flow name="graphql">
<http:listener config-ref="api-httpListenerConfig" path="/graphql" />

<graphql:router config-ref="graphql-config" payload="#[payload]" />
</flow>

<flow name="graphql:author">
<graphql:graphql-field-resolver
config-ref="graphql-config" fieldName="author" />

<scripting:execute engine="groovy">
<scripting:code>
payload = ['params' : attributes.getArguments(),
'fields' : attributes.getSelectionSet().get(),
'source' : 'person']
</scripting:code>
</scripting:execute>
<logger level="ERROR" message="Query params etc: #[payload]" />

<!-- Do query etc. if no field resolver needed it will just find it in 
the payload. obviously needs to match field names exactly etc. -->
<logger level="INFO" message="#[payload]" />
<set-payload
value="#[output application/java --- {'name' : 'ryan', 'anotherfield' :'a field that will not get returned'}]" />
</flow>

<flow name="graphql:books">
<graphql:graphql-field-resolver
config-ref="graphql-config" fieldName="books" />

<scripting:execute engine="groovy">
<scripting:code>
payload = attributes.getSource()
</scripting:code>
</scripting:execute>

<!-- Use these details to actually lookup books from a store, rest api 
or whatever. -->
<logger level="INFO" message="params etc: #[payload]" />

<set-payload
value="#[output application/java --- [{'name' :'Getting Started with Mule Cloud Connect'}]]" />
</flow>



</mule>

Basically, the module allows you to 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 its 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 configuration 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 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.

GraphQL Middleware

Published at DZone with permission of Ryan Carter, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Top 5 Java REST API Frameworks
  • Stream Processing vs. Batch Processing: What to Know
  • What Was the Question Again, ChatGPT?
  • An Introduction to Data Mesh

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: