Web Content API Basics Using GraphQL
Use Liferay DXP GraphQL services to manage web content by creating, retrieving, updating, and deleting structured content on your site. Structured content refers to web content articles that follow a defined structure, ensuring consistency across articles.
While you can use a structure with a web content template to render structured content, a template is not required for creating structured content.
For more advanced examples, refer to Advanced Web Content API. To get started with GraphQL in Liferay DXP, see Consuming GraphQL APIs.
Setting Up Your Environment
Start a new Liferay instance by running
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.120-ga120
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.
Then, follow these steps:
-
Download and unzip the Web Content API Basics files:
curl https://resources.learn.liferay.com/dxp/latest/en/content-authoring-and-management/web-content/developer-guide/liferay-r4h9.zip -O
unzip liferay-r4h9.zip
NoteThese scripts use basic authentication and are designed for testing. Do not use basic authentication in a production Liferay DXP environment.
-
Complete these steps to set up the environment:
Identifying the Services to Consume
Use the following services in the Liferay DXP Headless Delivery API to manage web content:
StructuredContent
for articles.ContentStructure
for structures.ContentTemplate
for templates.
To view detailed information on these APIs, use your browser and access Liferay API Explorer at [server]:[port]/o/api
(e.g. http://localhost:8080/o/api
). For more information, read Consuming REST Services.
Identifying the Site ID
When signed in, retrieve the site ID. Use this ID in several service calls. In this example, the ID is 20117
.
Creating a Web Content Structure in the User Interface
To create an article, you need a structure. When you create articles in the user interface without declaring a structure, Liferay DXP uses a default Basic Web Content structure.
The Basic Web Content structure is not visible in the Liferay DXP user interface.
Instead of using the Basic Web Content structure, create a new one:
-
Open the Site Menu (../../../images/icon-menu.png), expand Content & Data, and go to Web Content.
-
Select the Structures tab and click New.
-
Name it Foo Structure. In the Builder menu on the right, select, drag, and drop a Text field to the form area.
-
In the contextual menu that opens on the right, select the Advanced tab and change the Field Reference to
Content
. -
Click Save.
For more information, see Creating Structures.
Creating a Web Content Article in the User Interface
Now you can create an article based on the Foo Structure:
-
Open the Site Menu (../../../images/icon-menu.png), expand Content & Data, and go to Web Content.
-
Under the Web Content tab, click New and choose Foo Structure.
-
Enter Foo Article as the new name and click Publish.
For more information, see Creating Web Content Articles.
Getting Web Content Articles from the Site
Use GraphQL services to retrieve a list of the site’s articles. Access Liferay API Explorer to perform this action.
-
Navigate to Liferay API Explorer at
http://[host]:[port]/o/api
. -
Click GraphQL at the top-right of the screen to open Liferay’s GraphiQL browser.
-
Add the following query to the left column, and replace
siteKey
with your site ID to fetch theid
,key
,title
,friendlyUrlPath
, andcontentStructureId
for the articles in the given site:query { headlessDelivery_v1_0{ structuredContents(siteKey: "20117") { items { id key title friendlyUrlPath contentStructureId } } } }
NoteWith GraphQL you can specify the fields you need in your query response. You can adjust the queries/mutations in these examples by adding or removing fields to fit your requirements.
-
Click Execute Query. The response includes a list of article items with the queried information under each item:
{ "data": { "structuredContents": { "items": [ { "id": 32147, "key": "32145", "title": "Foo", "friendlyUrlPath": "foo", "contentStructureId": 32122 } ] } } }
Below are examples of calling other GraphQL services.
Getting a Web Content Article
While the script in the previous step returns all the site’s articles, you can get a specific article by using the structuredContent(structuredContentId)
query and specifying the article’s ID.
-
Click GraphQL in the top right corner, add the following query to the left column, and replace
structuredContentId
with your structure ID to fetch information about theid
,title
,friendlyUrlPath
, andcontentStructureId
:query { headlessDelivery_v1_0{ structuredContent(structuredContentId: 32147) { id title friendlyUrlPath contentStructureId } } }
-
Click Execute Query. The response includes the structure item’s queried information:
{ "data": { "structuredContent": { "id": 32147, "title": "Foo", "friendlyUrlPath": "foo", "contentStructureId": 32122 } } }
Getting Web Content Structures from the Site
Use the contentStructures
query to retrieve a list of the site’s structures.
-
Click GraphQL in the top right corner, add the following query to the left column, and replace
siteKey
with the site ID:query{ headlessDelivery_v1_0 { contentStructures(siteKey: "20117") { items { id name contentStructureFields { name label dataType } } } } }
-
Click Execute Query. The response returns what was informed in the query:
{ "data": { "headlessDelivery_v1_0": { "contentStructures": { "items": [ { "id": 32122, "name": "Foo", "contentStructureFields": [ { "name": "Content", "label": "Text", "dataType": "string" } ] } ] } } } }
Getting a Web Content Structure
Use the contentStructure
query to retrieve the description of a specific structure by providing its ID as a parameter.
-
Click GraphQL in the top right corner, add the following mutation to the left column, and replace
siteKey
with the site ID andcontentStructureId
with the ID of the structure you want to use:query{ headlessDelivery_v1_0{ contentStructure(contentStructureId: 32122){ id name contentStructureFields{ name label dataType } } } }
-
Click Execute Query. The response returns what was informed in the query:
{ "data": { "headlessDelivery_v1_0": { "contentStructure": { "id": 32122, "name": "Foo" "contentStructureFields": [ { "name": "Content", "label": "Text", "dataType": "string" } ] } } } }
Posting a Web Content Article
Use the createSiteStructuredContent
mutation to create a new article using the Foo Structure.
-
Click GraphQL in the top right corner, add the following mutation to the left column, and replace
siteKey
with the site ID andcontentStructureId
with the ID of the structure you want to use:mutation { headlessDelivery_v1_0{ createSiteStructuredContent( siteKey: "20117", structuredContent: { contentFields: [ { name: "Content", contentFieldValue: { data: "Goo" } } ], contentStructureId: 32122, title: "Goo Article" } ) { id title contentFields { name contentFieldValue { data } } } } }
-
Click Execute Query. The response returns what was informed in the mutation:
{ "data": { "createSiteStructuredContent": { "id": 32205, "title": "Goo Article", "contentFields": [ { "name": "Content", "contentFieldValue": { "data": "Goo" } } ] } } }
Patching a Web Content Article
Use the patchStructuredContent
mutation to update the article. It uses the structured content id
to update the article’s content from ‘Goo’ to ‘Foo’.
-
Click GraphQL in the top right corner, add the following mutation to the left column, and replace
structuredContentId
with the article ID andcontentStructureId
with the ID of the structure you want to use:mutation { headlessDelivery_v1_0{ patchStructuredContent( structuredContentId: 32215, structuredContent: { contentStructureId: 32122, title: "Updated Goo Article" contentFields: [ { name: "Content", contentFieldValue: { data: "Foo" } } ] } ) { id title contentFields { name contentFieldValue { data } } } } }
-
Click Execute Query. The response returns what was informed in the mutation:
{ "data": { "patchStructuredContent": { "id": 32215, "title": "Updated Goo Article", "contentFields": [ { "name": "Content", "contentFieldValue": { "data": "Foo" } } ] } } }
Putting a Web Content Article
Use the updateStructuredContent
mutation to replace the original article’s information. It uses the article and structure identifiers to replace the article’s name and the article’s content from Foo
to Bar
.
-
Click GraphQL in the top right corner, add the following mutation to the left column, and replace
structuredContentId
with the article ID andcontentStructureId
with the ID of the structure you want to use:mutation { headlessDelivery_v1_0{ updateStructuredContent( structuredContentId: 32215, structuredContent: { contentStructureId: 32122, title: "Bar Article" contentFields: [ { name: "Content", contentFieldValue: { data: "Bar" } } ] } ) { id title contentFields { name contentFieldValue { data } } } } }
-
Click Execute Query. The response returns what was informed in the mutation:
{ "data": { "updateStructuredContent": { "id": 32215, "title": "Bar Article", "contentFields": [ { "name": "Content", "contentFieldValue": { "data": "Bar" } } ] } } }
Deleting a Web Content Article
Use the deleteStructuredContent
mutation to delete an article. It uses the article’s id
to delete it.
When you delete articles using a GraphQL mutation, it’s deleted permanently, without using the Liferay DXP Recycle Bin.
-
Click GraphQL in the top right corner, add the following mutation to the left column, and replace
structuredContentId
with the article:mutation { headlessDelivery_v1_0{ deleteStructuredContent(structuredContentId: 32215) } }
-
Click Execute Query. The response returns a value indicating the deletion status:
{ "data": { "deleteStructuredContent": true } }
More Web Content and Web Content Folder Services
Use the following queries/mutations for more StructuredContent
and StructuredContentFolder
services.
File | Description |
---|---|
HeadlessDelivery_v1_0.structuredContentFolders: StructuredContentFolderPage | Lists a site’s web content folders. |
HeadlessDelivery_v1_0.structuredContentFolder: StructuredContentFolder | Retrieves a specific web content folder’s details |
MutationHeadlessDelivery_v1_0.createSiteStructuredContentFolder: StructuredContentFolder | Adds a new web content folder to a site. |
MutationHeadlessDelivery_v1_0.createStructuredContentFolderStructuredContentFolder: StructuredContentFolder | Adds a new web content folder to an existing folder |
MutationHeadlessDelivery_v1_0.patchStructuredContentFolder: StructuredContentFolder | Updates specific fields in a web content folder. |
MutationHeadlessDelivery_v1_0.updateStructuredContentFolder: StructuredContentFolder | Replaces a web content folder with new data. |
MutationHeadlessDelivery_v1_0.deleteStructuredContentFolder: Boolean | Deletes a web content folder. |
MutationHeadlessDelivery_v1_0.createStructuredContentFolderStructuredContent: StructuredContent | Adds a new web content article to an existing folder. |
Deleting a web content folder using a GraphQL mutation permanently removes the folder and its contents without using the Liferay DXP Recycle Bin.
To use these endpoints,
-
Identify the query/mutation name.
In
HeadlessDelivery_v1_0.structuredContentFolder: StructuredContentFolder
,HeadlessDelivery_V1_0
is the namespace,structuredContentFolder
is the query’s name andStructuredContentFolder
is the returned type.In
MutationHeadlessDelivery_v1_0.deleteStructuredContentFolder: Boolean
,Mutation
indicates this is a mutation. -
Use the query/mutation in GraphQL syntax (1). For
HeadlessDelivery_v1_0.structuredContentFolder: StructuredContentFolder
, the query would look like this:query { headlessDelivery_v1_0{ structuredContentFolder(structuredContentFolderId: 32344){ } } }
Use the GraphQL schema explorer (3) to understand which arguments to use.
-
Specify the return fields.
query { headlessDelivery_v1_0{ structuredContentFolder(structuredContentFolderId: 32344){ id name creator { id name } dateCreated } } }
-
Execute the query/mutation by clicking Execute Query. The response (2) should return the requested fields:
{ "data": { "headlessDelivery_v1_0": { "structuredContentFolder": { "id": 32344, "name": "folder", "creator": { "id": 20123, "name": "Portal Administrator" }, "dateCreated": "2024-11-05T12:20:56Z" } } } }