17 GraphQL Support in Oracle Content Management

Oracle Content Management includes support for GraphQL for all published content and all asset types. Developers can inspect the schema, build queries, and invoke them from clients alongside other delivery APIs.

GraphQL is a well-known query language for accessing content that is focused on fetching only the content that clients request and nothing more. GraphQL is designed to make APIs flexible and developer-friendly. To support this flexibility and power, GraphQL includes complete and inspectable schema that developers can build queries against in an intuitive way. For more information, visit https://graphql.org/ and https://spec.graphql.org/October2021/

The following sections describe how to work with GraphQL in Oracle Content Management:

Get Started with GraphQL

The quickest way to get started is by exploring schema and trying a few queries. Oracle Content Management includes a GraphQL IDE that helps you explore schema and run queries.

Explore Schema

The GraphQL IDE is available at http://your_instance/content/published/api/v1.1/graphql/explorer.

GraphQL user interface

In the Documentation Explorer (top right), search for an asset type by name to view the schema for that type. The image below shows an asset type named PressRelease. Every asset type in Oracle Content Management is represented by a GraphQL type of the same name (applying some helpful naming convention conversions). Every field in the asset type is represented by a GraphQL field with an equivalent data type.

pressRelease asset type

View the details of related types by clicking on the type's name. For example, all user defined fields of PressRelease are in the pressReleaseFields type (the last entry in the schema shown above). The image below shows the details you see after clicking pressReleaseFields.

pressRelease fields

Try Some Queries

GraphQL provides access to content through queries. Use the queries in this section, in GraphQL Queries, and in GraphQL Samples as examples.

To perform a content query, you need the IDs (or slugs) of a few published content items and the channelToken of the publishing channel. You type your query in the left panel, then click Run icon.

In the following example, we run a query with these parameters:

  • Asset type: PressRelease
  • Content item ID: CORE1FADA80EEACE4B4A84B76C07A931B317
  • Publishing channel token: 573ae0bcb95347d283cdbea8a4d29641
{
  getPressRelease(id: "CORE1FADA80EEACE4B4A84B76C07A931B317",
                  channelToken: "573ae0bcb95347d283cdbea8a4d29641") {
    id
    name
    description
  }
}

After running the query, you see the following.

getPressRelease query and response

You can include additional fields in your query, such as user defined fields, references to other assets, and so on. The IDE helps you along in your query by automatically filling in field names.

getPressRelease complex query and response

GraphQL Schema

GraphQL queries work against a schema or data model of the content. With Oracle Content Management, you don't need to create GraphQL schemas; every asset type in Oracle Content Management is automatically represented in the schema. The GraphQL type names are based on the API names of the asset types in Oracle Content Management, with prefixes where needed to avoid conflicts and collisions with reserved words in GraphQL.

Let's examine the schema for our PressRelease asset type in detail.

Types, Unions, and Interfaces

As we saw previously, the PressRelease asset type is represented by two GraphQL types—pressRelease and pressReleaseFields. The pressRelease type represents the core structure of the PressRelease asset type, including standard fields such as id, name, and description. The pressReleaseFields type, referenced in the pressRelease fields field, includes all user-defined fields. This structure mirrors how REST APIs express the field data.

pressRelease and pressReleaseFields schema described in text

In addition to the user-defined fields (such as title and abstract), the pressReleaseFields type includes the associated data types (see the mapping below). If the fields are set as required in the asset type, the GraphQL schema shows these fields as required (for example title: String!). If the fields are reference fields (Reference or Media), the GraphQL schema references the target's core asset type. For example, the author field references the pressReleaseAuthor asset type.

Reference fields in Oracle Content Management can accept more than one type. In such a scenario, a GraphQL union type is defined to represent such references. For example, the masthead field is declared with unionAllMediaTypes.

Notice that the pressRelease type implements an item; this is an interface item. The interface item (shown below) is the base for all core asset types in GraphQL. It includes access to taxonomies (taxonomies field) and translations (variation and variations fields). We'll discuss this more later.

Interface item schema
The table below shows the item interface fields.
Schema item
id: ID!
name: String!
type: String!
typeCategory: String
slug: String
language: String
translatable: Boolean!
description: String
createdDate: DateTime!
updatedDate: DateTime!
variation(variationType: String!, variationName: String): item
variations(variationType: String!): [item]
taxonomies: [taxonomy]

Data Types

Oracle Content Management data types are mapped to equivalent GraphQL types, native types where appropriate and scalars when needed. DateTime and JSON are scalars included automatically in the schema.

Oracle Content Management Data Type GraphQL Field Type
Boolean Boolean
Date DateTime
Decimal Float
JSON JSON
Large Text String
Media target asset type or union
Number Int
Reference target asset type or union
Text String

In addition to these data types, the Oracle Content Management ID for each asset is mapped to the ID field type in GraphQL.

GraphQL Queries

Oracle Content Management automatically generates queries for accessing assets. There is a generic item query (getItem(..)), and each core asset type gets a corresponding query (for example, getPressRelease(..)).

As previously mentioned, you type your query in the left panel, then click Run iconThe IDE will help you write your query, but here is the basic format you'll use to get an item, replacing the text in italics with the appropriate values. You must include a channelToken, either as an argument in the query or as a header in the HTTP request. You must include either the ID or slug of the asset.

{
    getItem(channelToken: channel_token, id: ID, slug: slug): item
}

or

{
    getPressRelease(channelToken: channel_token, id: ID, slug: slug): pressRelease
}

In addition to queries that fetch a single asset, GraphQL also supports fetching many assets together, optionally based on a filtering criteria and sort order. In order to do that an out of the box query is included in the schema.

{
	getItems(channelToken: String, 
filter: standardFilter, 
query: queryFilter, 
sort: [standardSort], 
limit: int, offset: int) : itemCollection
}

A few standard types are introduced to support this functionality:

  • standardFilter offers support for building filtering criteria for assets.
  • queryFilter supports searching across many fields.
  • standardSort specifies the sort order results based on field values.
  • limit and offset provides means for client to paginate results.

The results of this query is itself a type that is a collection of other items, itemCollection, which in turn has an items array, along with pagination details.

The standardFilter type is defined in the schema as an input type.

standardFilter type

The table below shows the standardFilter fields.
item standardFilter
id: idFilter
name: stringFilter
description: stringFilter
type: stringFilter
typeCategory: stringFilter
categories: assetCategoryFilter
slug: stringFilter
language: stringFilter
translatable: booleanFilter
createdDate: dateTimeFilter
updatedDate: dateTimeFilter
AND: [standardFilter]
OR: [standardFilter]
NOT: standardFilter

Field names in this type are the same the names of the standard fields in Oracle Content Management for the item. Values accepted for these fields are themselves an input type, such as stringFilter, idFilter and others. These input types are specific to the underlying data type of the field, which represents a tuple of operation and value. The stringFilter type is expanded below to show the shape of this tuple.

stringFilter and stringFilterOps types

With these data-type-specific input fields, a query can include only valid criteria for the data type. Please see GraphQL data types and available operations table for details.

In addition to the generic item query (getItems(..)) which uses the standardFilter type, GraphQL also supports type-specific queries with the ability to specify type-specific fields. To do this, for every asset type defined in Oracle Content Management, an accompanying type-specific filter is included. Continuing with the example of a PressRelease asset type, the filter for that is expressed as follows:

PressReleaseFieldsFilter type

Note that all fields present in the standardFilter type are available in the pressReleaseFilter type as well. This means, any query that is possible with the standardFilter type can also be built with the type-specific filter, but you can specify user-defined, field-specific filters as well. As with the standardFilter type, type-specific filters can be combined using AND, OR, and NOT.

Also note that type-specific fields include a field called fields that references another input type listing all user defined fields.

In addition to retrieving item content, the GraphQL schema also supports retrieving published taxonomy information using the following queries.

{
	getTaxonomy(channelToken: String, id: ID): taxonomy
}

and

{
	getTaxonomies(channelToken: String, sort: [taxonomySort]) : taxonomyCollection
}

Categories can be fetched either from a taxonomy or directly, using the following queries.

{
	getCategory(id: ID, taxonomyId: ID, channelToken: String, apiName: String): category
}
{
	getCategories(id: ID, taxonomyId: ID, channelToken: String, limit: int, offset: int): categoryCollection
}

Examples

Retrieve Assets: Filter and Sort Assets by Standard Fields

Retrieving assets by filtering using standard fields (name, id, description, type, and so on) is accomplished by the use of standardFilter. For example, retrieving assets of a specific type is accomplished by standardFilter using criteria based on the type field’s value.

{ getItems(channelToken: "573ae0bcb95347d283cdbea8a4d29641", filter: {type: {op: EQUALS, value: "MyType"}}) { totalResults items { id name description } }}

You could just as easily retrieve assets of more than one type by creating an OR condition in the standardFilter.

{
  getItems(channelToken: "573ae0bcb95347d283cdbea8a4d29641", 
    filter: { 
            OR: [
                {type: {op: EQUALS, value: "myType1"}}, 
                {type: {op: EQUALS, value: "myType2"}}
                ] 				}
  ) 
  
  {
    totalResults
    items {
      id
      name
      description
    }

Note that filtering is possible on any standard fields present in the Item interface. Each field offers various operations (such as EQUALS and NOT_EQUALS) depending on the data type. See the following table for available operations for each data type.

In addition to filtering, clients can specify sorting criteria for the query. The following example sorts the results by the name field’s value.

{
  getItems(channelToken: "573ae0bcb95347d283cdbea8a4d29641", 
    filter: {type: {op: EQUALS, value: "MyType"}}
    sort: {name :DESC}
  ) {
    totalResults
    items {
      id
      name
      description
    }
  }
}

In addition to the filtering and sorting, clients can specify pagination instructions by using limit and offset. The following example shows how a client can fetch up to 10 results (limit) after the first 20 (offset).

{
  getItems(channelToken: "573ae0bcb95347d283cdbea8a4d29641", 
    filter: {type: {op: EQUALS, value: "myType"}}
    sort: {name :DESC}
    limit: 10
    offset: 20
  ) {
    totalResults
    count
    items {
      id
      name
      description
    }
  }
}

Retrieving Assets of a Specific Type by Specifying a Type-Specific Filter

The filtering criteria in the following example includes a user-defined field title and queries for all PressRelease assets that have Oracle in the title field.

{
  getPressReleaseCollection(channelToken: "573ae0bcb95347d283cdbea8a4d29641", 
    filter: {fields: {title: {op: CONTAINS, value: "Oracle"}}}) {
    items {
      name
      id
    }
  }
}

As with any filters, type-specific filters can be nested.

{
  getPressReleaseCollection(channelToken: "573ae0bcb95347d283cdbea8a4d29641", 
    filter: {fields: {title: {op: CONTAINS, value: "Oracle"}}, AND: {language: {op: EQUALS, value: "en-US"}}}) {
    items {
      name
      id
      language
      fields {
        title
      }
    }
  }
}

Retrieve Taxonomy and Category Information

Just as in a single asset retrieval, taxonomy can be retrieved using getTaxonomy. The following example shows how a published taxonomy, along with the first 3 levels of category information, can retrieved.

{
  getTaxonomy(channelToken: "573ae0bcb95347d283cdbea8a4d29641", id: "F95CD0EB0E02427C9A3B7F1B8F33645C") {
    id
    name
    categories {
      id
      name
      children {
        id
        name
        children {
          id
          name
        }
      }
    }
  }
}

Likewise, it is possible to retrieve every published taxonomy by using getTaxonomies. The following example shows how to get every published taxonomy with first 3 levels of categories under each of them.

{
  getTaxonomies(channelToken: "573ae0bcb95347d283cdbea8a4d29641") {
    taxonomies {
      id
      name
      categories {
        id
        name
        children {
          id
          name
          children {
            id
            name
          }
        }
      }
    }
  }
}

Categories can themselves be listed as well as fetched by their id/apiName. The following example shows how to fetch a category by apiName and its children two levels down.

{
getCategory(channelToken:"573ae0bcb95347d283cdbea8a4d29641", taxonomyId: "F95CD0EB0E02427C9A3B7F1B8F33645C" apiName:"hk-p")
  {
    name
    id
    apiName
    children {
      name
      id
      apiName
    }
  }
}

GraphQL Support for Content Preview

GraphQL supports querying unpublished content similar to Content Preview REST APIs. See REST API for Content Preview.

Content that is published to a channel or targeted to a channel is available through Content Preview API in GraphQL. GraphQL preview provides access to the latest version of the asset.

In order to access assets in the preview context, the GraphQL endpoint is at http://user_instance/content/preview/api/v1.1/graphql and the GraphQL IDE is available at http://user_instance/content/preview/api/v1.1/graphql/explorer.

Previewing assets in GraphQL requires user authentication. See Authorization in REST API for Content Preview.

All the GraphQL capabilities (queries and schema) available for published assets are also available in preview.

GraphQL Samples

Retrieving An Asset's Data Using ID or Slug

The following query retrieves an asset's data using the asset's ID.

{
  getPressRelease(channelToken: "573ae0bcb95347d283cdbea8a4d29641", id: "CORE1FADA80EEACE4B4A84B76C07A931B317")
  {
    id
    fields {
      title
      abstract
      body
    }
  }
}

The following query produces identical results to the one above, using the slug instead of the ID.

{
  getPressRelease(channelToken: "573ae0bcb95347d283cdbea8a4d29641", slug: "bed-bath-beyond-selects-oracle-to-modernize-enterprise")
  {
    id
    fields {
      title
      abstract
      body
    }
  }
}

Retrieving a Referenced Asset's Data

The following query retrieves the referenced author type's fields along with the pressRelease fields.

{
  getPressRelease(channelToken: "573ae0bcb95347d283cdbea8a4d29641", slug: "bed-bath-beyond-selects-oracle-to-modernize-enterprise") {
    id
    fields {
      title
      abstract
      body
      author {
        fields {
          firstname
          lastname
          bio
        }
      }
    }
  }
}

Retrieving Renditions of Digital Assets

An out-of-the-box type called rendition is included in the schema to represent various media renditions. It provides easy access to URLs of the renditions so you can easily include them in your code. For example, the following query returns a large rendition of an image.

{
  getPressRelease(channelToken: "573ae0bcb95347d283cdbea8a4d29641", slug: "bed-bath-beyond-selects-oracle-to-modernize-enterprise") {
    id
    fields {
      title
      abstract
      body
      masthead {
        ...headerImage
      }
    }
  }
}
  fragment headerImage on image {
  id
  fields {
    rendition(name: "Large", format: "jpg") {
      file {
        url
      }
    }
  }
}

Instead of retrieving a specific rendition, you can retrieve a list of renditions (with both jpg and webp formats) with the renditions parameter.

{
  getPressRelease(channelToken: "573ae0bcb95347d283cdbea8a4d29641", slug: "bed-bath-beyond-selects-oracle-to-modernize-enterprise") {
    id
    fields {
      title
      abstract
      body
      masthead {
        ...headerImages
      }
    }
  }
}
  fragment headerImages on image {
  id
  fields {
    renditions {
      file {
        url
      }
    }
  }
}