Consuming GraphQL APIs
Liferay DXP contains GraphQL APIs for most of its applications. Here, you’ll learn how to consume them. This takes only three steps:
- Identify the API you wish to consume.
- Identify the site containing the data you need.
- Make the API call using credentials that have access to the data.
You need a running Liferay DXP to call its GraphQL APIs.
Start a new Liferay instance by running
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.86-ga86
Sign in to Liferay at http://localhost:8080. Use the email address test@liferay.com and the password test. When prompted, change the password to learn.
Identify the Service to Consume
Follow these steps:
Go to
http://localhost:8080/o/api
.At the top-left of the screen that appears, pick headless-delivery from the selector. This is the category that contains the Blog posting API.
Click the Show GraphQL button at the top-right of the screen to open Liferay’s GraphiQL browser.
Click the Docs link below the button you just clicked. Now you can browse the API.
GraphQL separates read and write operations by calling the first a query and the second a mutation. Since the first thing you want to do is post a blog entry, click mutation.
A list appears of the entire API use the search at the top or scroll down and find the call to
createSiteBlogPosting
:createSiteBlogPosting( blogPosting: InputBlogPosting siteKey: String! ): BlogPosting
You can also discover your local installation’s APIs by requesting the schema directly:
curl 'http://localhost:8080/o/graphql' -H 'Content-Type: application/json' --data '{"query":"query{ __schema{ queryType{ name fields{ name args{ name } description } } } }","variables":{}}'
This URL does not require authentication, but it’s quite cumbersome to manage the returned schema. For this reason, it’s better to use the included GraphQL client.
Since the API requires you to know the Site containing the Blog where the entry should be posted, you must find the Site ID first.
Identify the Site Containing the Data
Now you must find the Site ID:
Go to
http://localhost:8080
.Open the Global Menu
, click the Control Panel tab, and go to Sites → Sites.
Click the Actions button
next to the Liferay Site and choose Go to Site Settings.
Go to Site Configuration.
The Site ID appears at the top of the Details section. It’s an Integer, like 20122
.
Make the Service Call using Credentials with Access to the Data
Now you have everything you need to make the call. All web services must be accessed using credentials that have access to the data you’re requesting. The included GraphQL client authenticates using your browser. If your plan is to write a standalone client, you should authorize users via OAuth2.
During development, it’s much easier to use Basic Auth, which passes credential data in the URL. Since this is insecure, never use this method for production.
Calling a GraphQL API Using Basic Auth (During Development Only)
To call a service using Basic Auth, provide the credentials in the URL:
curl --request POST --url http://localhost:8080/o/graphql \ -u test@liferay.com:learn --header 'content-type: application/json' --data '{"query":"query {blogPostings(filter: \"\", page: 1, pageSize: 10, search: \"\", siteKey: \"20122\", sort: \"\"){ page items{ id articleBody headline creator{ name }}}}"}'
Calling a Service Using OAuth2
The use of GraphQL with OAuth2 is supported in Liferay DXP 7.4 U77+/Liferay Portal 7.4 GA77+
For production, create an OAuth2 application and use the OAuth2 process to get an authorization token. Once you have the token, provide it in the HTTP header:
curl --request POST --url http://localhost:8080/o/graphql -H "Authorization: Bearer d5571ff781dc555415c478872f0755c773fa159" --header 'content-type: application/json' --data '{"query":"query {blogPostings(filter: \"\", page: 1, pageSize: 10, search: \"\", siteKey: \"20122\", sort: \"\"){ page items{ id articleBody headline creator{ name }}}}"}'
Getting and Posting Data
In the top left window of the GraphQL client, place this code, which retrieves all blog entries:
query {blogPostings(filter:"",page:1,pageSize:10,search:"",siteKey:"20122",sort:"")
{page
items {
id
articleBody
headline
creator
{name
}
}
}
}
Click the play button to run it, and you’ll see there aren’t any blog entries:
{"data":{"blogPostings":{"page":1,"items":[]}}}
Now you’ll post a blog entry.
Posting a Blog Entry
The GraphQL schema revealed the call that must be made to post a blog entry.
Construct a JSON document containing the entry you wish to publish:
{ "blog": { "articleBody": "This Blog entry was created by calling the GraphQL service!", "headline": "GraphQL Blog Entry" } }
Construct the GraphQL query based on the schema documentation:
mutation CreateBlog($blog: InputBlogPosting){ createSiteBlogPosting(blogPosting: $blog, siteKey: "20122" ) { headline articleBody id friendlyUrlPath } }
Make the request by visiting
http://localhost:8080/o/api
again. Click the Show GraphQL button.Paste your JSON document into the Query Variables box at the lower left.
Paste your mutation in the unlabeled box at the top right.
Run your query by clicking the play button at the top.
The blog entry you added now appears in the GraphQL client’s right pane:
Liferay DXP returns a JSON representation of your blog entry that contains the fields you requested in the mutation:
{
"data": {
"createSiteBlogPosting": {
"headline": "GraphQL Blog Entry",
"articleBody": "This Blog entry was created by calling the GraphQL service!",
"id": 35541,
"friendlyUrlPath": "graphql-blog-entry"
}
}
}
You can make these requests with any web client, such as cURL:
curl --request POST --url http://localhost:8080/o/graphql -u test@liferay.com:learn --header 'content-type: application/json' --data '{"query":"mutation CreateBlog($blog: InputBlogPosting){ createSiteBlogPosting(blogPosting: $blog, siteKey: \"20122\" ) { headline articleBody id friendlyUrlPath } } ","variables":{"blog":{"articleBody":"This Blog entry was created by using cURL to call the GraphQL service!","headline":"cURL GraphQL Blog Entry"}},"operationName":"CreateBlog"}'
Getting All Blog Entries
Now you can repeat the first query you did:
query {blogPostings(filter:"",page:1,pageSize:10,search:"",siteKey:"20122",sort:"")
{page
items {
id
articleBody
headline
creator
{name
}
}
}
}
Liferay DXP returns JSON containing the blog entry you posted:
{
"data": {
"blogPostings": {
"page": 1,
"items": [
{
"id": 35541,
"articleBody": "This Blog entry was created by calling the GraphQL service!",
"headline": "GraphQL Blog Entry",
"creator": {
"name": "Test Test"
}
}
]
}
}
}
Getting a Single Blog Entry
The API call from the GraphQL schema for getting a single Blog entry has only one parameter:
blogPosting(
blogPostingId: Long
): BlogPosting
Since the query above revealed your Blog post’s ID, you can retrieve just the post you want:
query {blogPosting(blogPostingId: 35541)
{ id
headline
articleBody}
}
Paste this into the top left window of the client and click the Play button. It returns the same blog entry:
{
"data": {
"blogPosting": {
"id": 35541,
"headline": "GraphQL Blog Entry",
"articleBody": "This Blog entry was created by calling the GraphQL service!"
}
}
}
Deleting a Blog Entry
Deleting a blog entry, like creating one, is a mutation. Its call is almost the same as getting a single blog entry:
deleteBlogPosting(
blogPostingId: Long
): Boolean
Using the client, you can make the call like this:
mutation {
deleteBlogPosting(blogPostingId: 35541)
}
This call returns a Boolean in a JSON document denoting success or failure:
{
"data": {
"deleteBlogPosting": true
}
}
Congratulations! You’ve now learned how to call Liferay DXP’s GraphQL services. Remember that the examples above use Basic Auth: for production, use OAuth2 to call services in a secure way.