Getting to know the API
Contents
Based on the developer environment you created in the previous chapter, you’ll now install and test Enonic’s headless graphql API, aka Guillotine
Headless API
Enonic provides an out-of-the-box GraphQL API that dynamically reflects changes in your applications and content.The API is highly flexible, and may even be customized.For a deep dive, visit the Guillotine documentation.
New to GraphQL?Check out the GraphQL documentation |
Task: Install API
The headless API can be installed via an application called Guillotine
.
-
Install via XP menu (XP icon in the top right corner) →
Applications
→Install
. Search forGuillotine
and install the app. -
Once installed, Guillotine will automatically create and expose a GraphQL API for your application and project. You can verify that Guillotine is working by opening Content Studio. Look for a new menu item on the left called
Query Playground
.
Accessing the API externally
Guillotine application creates a graphQL API endpoint for every site that it is added to. So if your Enonic XP is running on http://localhost:8080
, you will get the following URLs for every site with Guillotine app added:
http://localhost:8080/site/[project-name]/[branch-name]
where branch-name
can only be draft
or master
, with draft
being protected by authentication.
Task: Run a simple query
Query playground lets us browse and use the API directly. Use the left hand field to type/paste in queries, press the "play" button to run the query, and the result will be presented in the right hand field.
-
Query movies:
One of the objectives in this tutorial is listing and presenting movie details. Run this simple query that retrieves the ID and displayName of some movies:
Query to fetch movies from the Headless API:{ guillotine { queryDsl( query: { boolean: { must:[ {term: {field: "valid", value: {boolean:true}}} {term: {field: "type", value: {string: "com.example.myproject:movie"}}} ] } } sort: { field:"displayName" direction:ASC } ) { id: _id displayName } } }
com.example.myproject
refers to the name of the application you created in the previous chapter.movie
is a specific content type within the app. -
View the Result
After executing the query, you should get a result in the right hand response panel.
Task: Query variables
In addition to the query itself, GraphQL also supports optional query variables
. Query variables enable you to re-use the same query, but for instance fetch different content each time.
-
Add query to the GraphQL playground:
query($path:ID!){ (1) guillotine { get(key:$path) { (2) type _id displayName } } }
1 path
is declared (with a$
marking it as a variable in the query). The declaration includes its type (ID
), and a!
marking it as a required parameter).2 The path
variable here used as the value of thekey
parameter, passed to theget
field. -
Add query Variables. In the bottom left of Query Playground, you will find a the `Query variables`tab. Add the following JSON to the field.
Tthe path
field in the JSON corresponds to the$path
in the query string above:{ "path": "/movies/se7en" }
-
Run the query to validate that the parameter working as expected.
Task: Type introspection
The queries above only specify fields like _id
and displayName
for each content found. These are general fields in the CMS, available across all content types.
Content types may also define their own custom fields. These are stored under the data
field. In the headless API, deeper data and functionality belonging to a content type is accessed through introspection.
For example, you may introspect the fields that are exclusive to the com.example.myproject:movie
content type like this:
... on com_example_myproject_Movie
The fully-qualified content type name is used, dots are replaced with underscores, and the name is capitalized Movie . |
-
Fetch a complex data set
Lets get content for a movie, the referenced image items
media:image
and person itemscom.example.myproject:person
in a single query:Paste this query into the GraphQL Playground:
A query with nested introspectionsquery($path:ID!){ guillotine { get(key:$path) { type displayName ... on com_example_myproject_Movie { data { subtitle abstract trailer release photos { ... on media_Image { imageUrl: imageUrl(type: absolute, scale: "width(500)") } } cast { character actor { displayName ... on com_example_myproject_Person { _path data { photos { ... on media_Image { imageUrl: imageUrl(type: absolute, scale: "block(100,100)") } } } } } } } } } } }
1 Notice how imageUrl
is requested with parameters of its own? Type introspections can expose certain functions for processing data before returning it.Run the query in the Playground. It should produce a complete set of data - which will come in handy later in this tutorial.
All in all, this allows for fetching deep and rich content data in a single API request.
Moving forward, you’ll get introduced to the concept of sites.