How to Expose GraphQL API In MuleSoft
Expose GraphQL API in MuleSoft
In this blog, let us discuss how to expose GraphQL API in MuleSoft.
- We would be exposing a GraphQL API in MuleSoft which would allow us to get 2 resources that are exposed as REST APIs.
- Here, we can consume a single GraphQL API Endpoint to consume both resources rather than sending requests to the individual Exposed APIs.
- We can also limit the number of fields that would be returned using the request that would be sent to the GraphQL API itself and we don’t need to make any changes in the individual REST APIs that are exposed.
Pre-Requisites:
- We need to have 2 REST APIs exposed which would be utilized by the GraphQL API.
- In my scenario, I am utilizing 2 REST APIs that are exposed. One of the endpoint is getProducts which is used to fetch the details regarding all the products present and the second endpoint is getProductsById which would return a particular product detail according to the id that is passed.
Now, let us see the steps to achieve this.
Step 1: First, we need to create a Schema. Schema will give the framework for the GraphQL API that we are going to expose.
- We need to create a schema file in our local directory which will be imported. For creating the same you can use a text file that needs to be saved as a .graphql file.
Step 2: Now, we need to publish the schema to the AnyPoint Exchange. For that, we should navigate to the exchange and we need to select publish a new asset. There we need to fill in some details. Select the asset type as GraphQL API, select the schema file, and click on publish.
- Once we publish it, it will be visible in the exchange.
Step 3: Now we need to create an Implementation for the schema published in the exchange. I will be using AnyPoint Code Builder, a cloud-based IDE for building the implementation. In code builder, we need to select Implement an API from the quick actions.
Step 4: Once we click the implement an API option, we need to specify the name of the project, select the home folder, and select the schema that we have published in the exchange. Once the options are selected, we can click Create Project.
Step 5: Once you click create the project, the entire flow will get generated just like in AnyPoint Studio which will contain an explorer on the left-hand side, a graphical representation of the flow in the middle, and the XML related to the flow in the right-hand side.
Step 6: Here, in the graphical interface you can add new components and the details related to the component should be added in the XML. There would be 3 flows that would be created in my case the main flow, the get products flow, and the get products by id flow. You can switch between the flows by using the flow list option at the top. If you notice, the XML that is created will contain all the details related to all the 3 flows. We need to make some changes to the XML. Where we need to add the following details:
<?xml version=’1.0′ encoding=’UTF-8′?>
<mule xmlns=”http://www.mulesoft.org/schema/mule/core” xmlns:doc=”http://www.mulesoft.org/schema/mule/documentation” xmlns:http=”http://www.mulesoft.org/schema/mule/http” xmlns:graphql-router=”http://www.mulesoft.org/schema/mule/graphql-router” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:ee=”http://www.mulesoft.org/schema/mule/ee/core” 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/graphql-router http://www.mulesoft.org/schema/mule/graphql-router/current/mule-graphql-router.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd”>
<flow name=”api-main-flow”>
<http:listener xmlns:http=”http://www.mulesoft.org/schema/mule/http” config-ref=”http-listener-config” path=”${http.listener.path}” />
<graphql-router:route xmlns:graphql-router=”http://www.mulesoft.org/schema/mule/graphql-router” config-ref=”GraphQL_Router_Config” />
</flow>
<flow name=”Query.productById”>
<graphql-router:data-fetcher xmlns:graphql-router=”http://www.mulesoft.org/schema/mule/graphql-router” config-ref=”GraphQL_Router_Config” objectTypeName=”Query” fieldName=”productById” />
<http:request method=”GET” doc:name=”Request” doc:id=”9007ba6a-8019-438a-9415-892c8294a14d” config-ref=”Product API Config” path=”/products/{productid}”>
<http:uri-params>
<![CDATA[#[%dw 2.0 output application/json — {
“productid”: attributes.arguments.id
}]]]>
</http:uri-params>
</http:request>
<graphql-router:serialize xmlns:graphql-router=”http://www.mulesoft.org/schema/mule/graphql-router” config-ref=”GraphQL_Router_Config” objectTypeName=”Query” fieldName=”productById” />
</flow>
<flow name=”Query.products”>
<graphql-router:data-fetcher xmlns:graphql-router=”http://www.mulesoft.org/schema/mule/graphql-router” config-ref=”GraphQL_Router_Config” objectTypeName=”Query” fieldName=”products” />
<http:request method=”GET” doc:name=”Request” doc:id=”8007ba6a-8019-438a-9415-892c8294a14d” config-ref=”Product API Config” path=”/products”></http:request>
<ee:transform doc:name=”Transform Message” doc:id=”lvtqis”>
<ee:message>
<ee:set-payload doc:name=”Set payload” doc:id=”wxopxb”>
<![CDATA[%dw 2.0
output application/json
—
payload.products
]]>
</ee:set-payload>
</ee:message>
</ee:transform>
<graphql-router:serialize xmlns:graphql-router=”http://www.mulesoft.org/schema/mule/graphql-router” config-ref=”GraphQL_Router_Config” objectTypeName=”Query” fieldName=”products” />
</flow>
</mule>
- Here, I have added the details for each flow that is needed where, In the main flow I would have a Listener and a GraphQL Router. In the get products flow I will have a Data fetcher at the start, a request component, and a transform message which will set the response payload as JSON and in the end a Serialize component. In the get products by ID flow, I will have a Data Fetcher at the start, we will have a request component, in which I will be setting a URI parameter and a Serialize component at the end.
Step 7: Now, there is a global-config file that is used to define the configurations for the components as well as to define configuration property and global property values. We need to configure the Listener config, Request config as well as GraphQL Router config.
Step 8: Once the configurations are done, we can deploy and test the API. To deploy it we can use the Run and Debug option and click the play icon and you would be able to see that the API is getting deployed in the console.
Step 9: To test this API, we can make use of the terminal which is available in the code builder itself, where we need to pass the request in the format of curl. We can use the + symbol in the right-hand corner for creating a new terminal for testing.
Step 10: First let’s start with testing get products,
- Scenario-1: We need to get all the fields related to the products. The curl that should be sent would look like this:
Request:
curl –request POST \
–location ‘http://localhost:8081/graphql’ \
–header ‘Content-Type: application/json’ \
–data ‘{
“query”: “query products {
products{
id
title
description
price
discountPercentage
rating
stock
brand
category
thumbnail
images
}
}”
}’
Response:
- Scenario-2: We need to get only the fields id, title, and description related to the products. The curl that should be sent would look like this:
Request:
curl –request POST \
–location ‘http://localhost:8081/graphql’ \
–header ‘Content-Type: application/json’ \
–data ‘{
“query”: “query products {
products{
id
title
description
}
}”
}’
Response:
Step 11: Now, let’s test get products by id:
- Scenario-1: We need to get all the fields related to a particular id. The curl would look like:
Request:
curl –request POST \
–location ‘http://localhost:8081/graphql’ \
–header ‘Content-Type: application/json’ \
–data ‘{
“query”: “query productById($id: ID){
productById(id: $id) {
id
title
description
price
discountPercentage
rating
stock
brand
category
thumbnail
images
}
}”,
“variables”: {
“id”:4
}
}’
Response:
- Scenario-2: We need to get only the id, title, and description of the product based on the id. The curl that should be sent would look like this:
Request:
curl –request POST \
–location ‘http://localhost:8081/graphql’ \
–header ‘Content-Type: application/json’ \
–data ‘{
“query”: “query productById($id: ID){
productById(id: $id) {
id
title
description
}
}”,
“variables”:{
“id”:4
}
}’
Response: