Tutorial: Programmatically creating a GraphQL endpoint for an admin team
In this tutorial, you will programmatically create a GraphQL endpoint so that an administrator can manage it later in Brightspot. The endpoint requirements are as follows:
- The endpoint should be able to fetch data from a content type that you define.
- When the endpoint is deployed, it should be immediately available to the administrator.
- The administrator should be able to control whether or not an API key is required.
- The administrator should be able to control whether or not introspective queries are allowed in certain environments.
Because your admin team includes individuals of varying technical expertise, you will limit the number of configurable fields to only the two listed above—Access Option and Allow Introspection Queries—helping prevent mis-configuration of the endpoint. For a look into the administrator's role in this process, see Tutorial: Creating and expanding access for an endpoint in Brightspot.
In this tutorial, you will:
- Create a data model and view model.
- Create a Java class that will contain the endpoint configuration.
- Add a URL path from which the endpoint can be accessed.
- Configure the endpoint to fetch data from the data model.
- Allow an administrator to control whether or not an API key is required.
- Allow an administrator to control whether or not to allow introspective queries.
Assumptions
This tutorial assumes the following:
- Familiarity with Brightspot's Java APIs
- Familiarity with GraphQL
Step 1: Create a data model and view model
As a prerequisite for this tutorial, you will create two Java classes for your data model and view model, respectively.
For the data model, you will create a Java class named Product that extends Content.
1public class Product extends Content {23private String name;45private String description;67private String color;89public String getName() {10return name;11}1213public String getDescription() {14return description;15}1617public String getColor() {18return color;19}20}
For the view model, you will create a Java class named ProductViewModel that extends ViewModel<Product>.
1@ViewInterface2public class ProductViewModel extends ViewModel<Product> {34public String getColor() {5return model.getColor();6}78public String getName() {9return model.getName();10}1112public String getMessage() {13return String.format("%s: %s: %s", getName(), getColor(), model.getDescription());14}15}
Step 2: Create a Java class that will contain the endpoint configuration
In this step, you will be creating a single instance of a Java class named ProductDeliveryEndpoint that extends ContentDeliveryApiEndpoint. Because you will implement Singleton, the endpoint will be immediately available to the administrator when you deploy the code.
This tutorial outlines the creation of a delivery API endpoint. For more information on management API endpoints, see Hello Content Management API.
1@DisplayName("Product Delivery API")2public class ProductDeliveryEndpoint extends ContentDeliveryApiEndpoint implements Singleton {
Step 3: Add a URL path from which the endpoint can be accessed
In this step, you will specify a URL path with which to hit the endpoint. Endpoint URL paths are tied to Brightspot's permalink system, which automatically validates a given URL path for uniqueness.
1@Override2public Set<String> getPaths() {3return Collections.singleton("/product-delivery-api");4}
- 2. This API allows you to specify multiple URL paths from which the endpoint can be accessed; however, for the purposes of this tutorial, you will create only one.
To hit the endpoint, append the URL path above onto the domain of your Brightspot instance (for example: https://cms.example.com/product-delivery-api-endpoint).
Step 4: Configuring the endpoint to fetch data from the data model
In this step, you will configure the endpoint so that it can fetch data. You will do this by creating a query entry field—a top-level field on the Query type—for use with your endpoint.
1@Override2public List<ContentDeliveryEntryPointField> getQueryEntryFields() {3return Collections.singletonList(4new ContentDeliveryEntryPointField(ProductViewModel.class));5}
- 4. References the view model you created in step 2 of this tutorial.
Step 5: Allow an administrator to control whether or not an API key is required
In this step, you will make the endpoint's access level configurable for an administrator. Over the course of the exercise, you will expand the code to control the future use of the field and prevent a validation error from occurring upon save.
-
Define the editorial field.
showLineNumbers1@Embedded2private GraphQLApiAccessOption accessOption; -
Override the
getApiAccessOptionmethod, returning the editorially-specified value of the newly added field.showLineNumbers1@Override2public GraphQLApiAccessOption getApiAccessOption() {3return accessOption;4} -
Make the field required.
We add the
@Requiredannotation here which has the effect of an error message displaying in the Brightspot UI if a user attempts to submit the form with a blank value for the field.showLineNumbers1@Embedded2@Required3private GraphQLApiAccessOption accessOption; -
Prevent a validation exception on save.
Because it is a
Singleton, Brightspot will attempt to save the instance of the endpoint the first time you deploy the code. Since the Access Option field has no value yet, the save would fail with a validation error (because of the aforementioned@Requiredannotation). The followingbeforeSave()implementation mitigates this problem by defaulting the value to an option that requires an API key.showLineNumbers1@Override2protected void beforeSave() {3super.beforeSave();45if (accessOption == null) {6accessOption = new GraphQLApiAccessOptionExplicit();7}8}
Your code should now look similar to the following:
1@Embedded2@Required3private GraphQLApiAccessOption accessOption;45@Override6public GraphQLApiAccessOption getApiAccessOption() {7return accessOption;8}910@Override11protected void beforeSave() {12super.beforeSave();1314if (accessOption == null) {15accessOption = new GraphQLApiAccessOptionExplicit();16}17}
Step 6: Allow an administrator to control whether or not to allow introspective queries
For the purposes of this tutorial, the company that gave you these endpoint requirements has three environments: QA, UAT, and Production. An administrator may want to configure whether introspection queries are allowed on a per-environment basis; to facilitate that, in this step you will add a Allow Introspection Queries toggle field to Brightspot.
1private Boolean allowIntrospectionQueries;23@Override4public IntrospectionQueryRule getIntrospectionQueryRule() {5return () -> Boolean.TRUE.equals(allowIntrospectionQueries);6}
Result
All together, your data model, view model, and endpoint now resemble the following code snippets:
Product.java
1public class Product extends Content {23private String name;45private String description;67private String color;89public String getName() {10return name;11}1213public String getDescription() {14return description;15}1617public String getColor() {18return color;19}20}
ProductViewModel.java
1@ViewInterface2public class ProductViewModel extends ViewModel<Product> {34public String getColor() {5return model.getColor();6}78public String getName() {9return model.getName();10}1112public String getMessage() {13return String.format("%s: %s: %s", getName(), getColor(), model.getDescription());14}15}
ProductDeliveryEndpoint.java
1@Recordable.DisplayName("Product Delivery API")2public class ProductDeliveryEndpoint extends ContentDeliveryApiEndpoint implements Singleton {34@Embedded5@Required6private GraphQLApiAccessOption accessOption;78private Boolean allowIntrospectionQueries;910@Override11public List<ContentDeliveryEntryPointField> getQueryEntryFields() {12return Collections.singletonList(13new ContentDeliveryEntryPointField(ProductViewModel.class));14}1516@Override17public Set<String> getPaths() {18return Collections.singleton("/product-delivery-api");19}2021@Override22public GraphQLApiAccessOption getApiAccessOption() {23return accessOption;24}2526@Override27public IntrospectionQueryRule getIntrospectionQueryRule() {28return () -> Boolean.TRUE.equals(allowIntrospectionQueries);29}3031@Override32protected void beforeSave() {33super.beforeSave();3435if (accessOption == null) {36accessOption = new GraphQLApiAccessOptionExplicit();37}38}39}
After adding the following method and deploying the code, it will be the responsibility of the administrator to generate the API key and associate it with the endpoint. For a look into an administrator's role, see Tutorial: Creating and expanding access for an endpoint in Brightspot.