Getting to know the API

Contents

Based on the developer environment you setup in the previous chapter, you’ll now learn about Enonic’s headless graphql API, aka Guillotine

Headless API

Enonic provides and out-of-the-box GraphQL API that dynamically to reflects your site’s content types and data model. The API is very flexible, and the developer controls the version of the API being used, and may even customize it. For more details on the foundations of the API, visit the Guillotine documentation.

New to GraphQL? Check out the GraphQL documentation

Task: Run a simple query

  1. Access the guillotine API:

    Visit this link http://localhost:8080/site/hmdb/draft/hmdb/_graphql to access the Headless API, and the draft content items.

    graphql playground

    The interface served when we access the endpoint lets us browse the API directly. Use the tabs on the far right to discover. Use the left hand field to type/paste in queries, press the "play" button in the middle to run the query, and the result will be presented in the right hand field.

  2. 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 {
            query(query: "valid='true' and type='com.example.myproject:movie'", sort: "displayName") {
                id: _id
                displayName
            }
        }
    }
  3. View the Result

    After executing the query, you should get a result in the right panel. graphql query

Task: Query variables

In addition to the query itself, GraphQL also supports optional variables. Variables enable you to re-use the same query, but for instance fetch different content each time.

  1. 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 the key parameter, passed to the get field.
  2. Add query Variables using the tab at the bottom to add a variables JSON object. Notice how the path field corresponds to the $path in the query string.:

    {
        "path": "${site}/movies/se7en"
    }
    ${site} is a valid path element in Guillotine paths, and will internally resolve the path of the site and expand it - in this case the full path will be expanded to /hmdb/movies/se7en.
  3. Run the query with the variables, and see the result.

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:

Content type introspection:
... on com_example_myproject_Movie
The fully-qualified content type name is used, dots are replaced with underscores, and the name is capitalized Movie.
  1. Fetch a complex data set

    Lets get content for a movie, the referenced image items media:image and person items com.example.myproject:person in a single query:

    Copy this query into the GraphQL playground…​

    A query with nested introspections
    query($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 See how imageUrl is requested with parameters of its own? Type introspections can expose certain functions for processing data before returning it.

    Since the query is still parameterized with $path, we can use the same variables object used earlier

    Variables
    {
        "path": "${site}/movies/pulp-fiction"
    }

    Run the query in the playground. It should produce a fully resolved 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.

Coming up - get up and running with your Next.js developer environment.


Contents