Use GraphQL with React and Oracle Content Management
Introduction
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.
In this tutorial, we’ll show how to use GraphQL with React connected to Oracle Content Management. In particular, we’ll focus on the existing ‘People’ page on the React minimal sample site by querying the necessary data using GraphQL and Apollo client. The other pages (‘Home’ and ‘Contact Us’) are currently using a REST API.
Prerequisites
Before proceeding with this tutorial, we recommend that you read the following information first:
To follow this tutorial, you’ll need:
- an Oracle Content Management subscription
- an Oracle Content Management account with the Content Administrator role
- the completed tutorial to build a minimal site in React
What We’re Building
With the minimal site built in React, you can easily retrieve images and other content from your Oracle Content Management repository.
To take a look at what we’re building, here’s the end state of our tutorial, a basic React minimal site that consumes content from Oracle Content Management:
https://headless.mycontentdemo.com/samples/oce-react-minimal-sample
This tutorial will focus solely on the ‘People’ page of this site.
This is what the People page will look like at the end of this tutorial:
To proceed, you’ll need to have an active subscription to Oracle Content Management and be logged in with the Content Administrator role.
Task 1: Understand the People Page Taxonomy
The downloadable asset pack contains an asset called Minimal Main GraphQL with the slug ‘minimalmaingraphql’.
The Minimal Main GraphQL asset contains a page of type PeoplePage called People. This is what it looks like:
The People asset is of type PeoplePage, and it contains subtypes of people. This is what it looks like:
This is what an example people asset looks like (note all the metadata in the Attributes panel):
Task 2: Use Apollo Client
To query these assets from Oracle Content Management using GraphQL, we need add the “@apollo/client” dependency in the package.json file.
The endpoint for the GraphQL API is the server URL concatenated
with /content/published/api/v1.1/graphql
, and is
defined in the src/scripts/services-graphql.js file.
const SERVER_URL_GRAPHQL = `${process.env.SERVER_URL}/content/published/api/v1.1/graphql`;
Task 3: Run and Process the GraphQL query
The src/pages/Routes.js file defines the routes for the application. The /page/people path is directed to the People component.
export default [
{...App,
routes: [
{...People,
path: '/page/people',
exact: true,
title: 'People',
,
}
{...Page,
path: '/page/:slug',
exact: true,
title: 'Page',
,
},
],
}; ]
The People component is responsible for rendering the People Page. Open the People component, located at src/pages/People.jsx.
The fetchInitialData function is called during server-side rendering to get the data from the server.
import fetchPeople from '../scripts/services-graphql';
function fetchInitialData(req) {
const pageslug = req.path.split('/').pop();
return fetchPeople(pageslug);
}
The componentDidUpdate function checks if the location
pathname
has changed, which indicates a navigation
change, and then fetches data accordingly.
componentDidUpdate() {
const { pageSlug } = this.state;
const { location } = this.props;
const { pathname } = location;
const newSlug = pathname.split('/').pop();
if (pageSlug !== newSlug) {
this.fetchData(newSlug);
}
}// Client Side Data Fetching: called from Client when doing client side routing/hydration
async fetchData(slug) {
const pageData = await fetchPeople(slug);
document.title = pageData.name;
this.setState(() => ({
,
pageDatapageSlug: slug,
;
})) }
In the render() method, you can see that the data to render is obtained from the component’s state. This data has an announcement section and a list of persons, so the People component’s render() method iterates through the list and calls the Person component for each person in the list.
The People component exports an object containing the fetchInitialData function and the component.
export default {
,
fetchInitialDatacomponent: People,
; }
The fetchPeople method is defined in the src/scripts/services-graphql.js file and uses the Apollo client to make the query below to obtain all the data for the People page.
More information about how to query data using Oracle Content Management can be found in the documentation.
const GET_PEOPLE_PAGE = gql`
query ($peopleSlug: String!, $channelToken: String!){
getPeoplePage(slug: $peopleSlug, channelToken: $channelToken) {
id
slug
name
fields {
announcement {
id
fields {
type: fieldType
heading
body
actions
image {
...sectionImages
}
}
}
people {
id
fields {
fullname
title
biodata
file {
metadata {
width
height
}
}
renditions {
name
format
file {
url
metadata {
height
width
}
}
}
}
}
}
}
}
fragment sectionImages on image {
id
fields {
file {
metadata {
width
height
}
}
renditions {
name
format
file {
url
metadata {
height
width
}
}
}
}
}`;
export default async function fetchPeople(peopleSlug) {
// Get the page details
const channelToken = `${process.env.CHANNEL_TOKEN}`;
const client = new ApolloClient(
{link: new HttpLink({ uri: SERVER_URL_GRAPHQL, fetch }),
cache: new InMemoryCache(),
,
};
)const page = await client.query({
query: GET_PEOPLE_PAGE,
variables: { peopleSlug, channelToken },
;
})
const pageData = process.env.IS_BROWSER
? page.data.getPeoplePage
: JSON.parse(JSON.stringify(page.data.getPeoplePage));
const { people, announcement } = pageData.fields;
if (announcement.fields.image) {
.renditionURLs = getSourceSetGraphQL(announcement.fields.image);
announcement
}if (people) {
.forEach((person) => {
people.renditionURLs = getSourceSetGraphQL(person);
person;
})
}return pageData;
}
The returned result is then processed to create the HTML to display the People page. The GraphQL IDE is available at http://your_instance/content/published/api/v1.1/graphql/explorer.
Preview API content using GraphQL
GraphQL support for Content Preview is also available as well and is fairly simple to implement. More information about using the preview API with GraphQL can be found here.
For preview calls using the content SDK, the only thing needed is to create the appropriate client as specified in the file server-config-utils.js
if (process.env.PREVIEW === 'true') {
clientInstance = createPreviewClient(serverconfig);
} else {
clientInstance = createDeliveryClient(serverconfig);
}
For graphql calls we need to specify the correct endpoint as specified in the file services-graphql.js
let serverUrlGraphQL = isPreview
? '/content/preview/api/v1.1/graphql'
: `${process.env.SERVER_URL}/content/published/api/v1.1/graphql`;
if (hostUrl != null && isPreview) {
serverUrlGraphQL = `${hostUrl}/content/preview/api/v1.1/graphql`;
}
To switch over to using preview mode, the change is as simple as updating the .env file for the project to include additional variables. A complete guide about preview mode settings and how to obtain these environment variables for your instance can be found here. Most notably, you will need to set PREVIEW, OPTIONS, and AUTH/AUTH_PARAMS in the .env file according to the linked documentation for setting the AUTH/AUTH_PARAMS for your specific instance.
Conclusion
In this tutorial, we added a ‘People’ page to the React minimal sample site using GraphQL to obtain the data for that page. The other pages (‘Home’ and ‘Contact Us’) still use the REST API.
Additional information on GraphQL in Oracle Content Management can be found in the documentation.
Use GraphQL with React and Oracle Content Management
F51096-02
February 2023
Copyright © 2021, 2023, Oracle and/or its affiliates.
Primary Author: Oracle Corporation