Content Delivery API
The Content Delivery API gives clients access to their Brightspot View model, and is the best way to use Brightspot as a headless CMS to power your custom frontend.
This API is available for all Sites hosted by your Brightspot application. Each Site has a unique domain or sub-domain through which you can access the API Endpoint. For each Site, the API lives at the path /delivery/graphql
. So, if you have a site hosted at https://example.com
, and you want to access the API, you need to send requests to the URL https://example.com/delivery/graphql
. The API will only return content that is accessible to that Site as determined by the Site and Content specific permissions.
The operations you can perform are all strictly typed, and there is just one query
operation for each type. The total number of types represented in the API is roughly equal to the total number of concrete view-model classes plus the total number of non-concrete view-model classes that are annotated with @ViewInterface. There are certain conditions that must be met for a view-model class to be represented and therefore the actual number can be less. Here is a templated snippet of a generated schema, where _ViewModelType_
represents a single ViewModel
class in the system.
schema { query: Query } type Query { PageEntryView(id: ID, path: String): com_psddev_cms_view_PageEntryView _ViewModelType_(id: ID, path: String): _ViewModelType_ # repeat for each content type } union PageEntryView = _ViewModelType_ # One for each View type type _ViewModelType_ { _modelId: ID _modelType: ID # ViewModel specific fields here }
PageEntryView
is a special union
type that represents any type that has a path associated with it. This is useful when you are requesting a path and you do not know what type of content lives at that path.
The query
operation, named after the ViewModel
type it returns, accepts either an ID or a path as input. The ID or path in this case belongs to the backing data model. All viewmodels are backed by some model. The subset of those that are represented in the query
API are backed by a Data model, which is a Recordable
object that's stored in the database and has an ID (and optionally a path or "permalink") associated with it. That is to say, the view model itself does not have its own ID, only a class identifier.
Consider the following example:
Backend Code
public class Article extends Content { @Indexed public String title; } public class Foo { } @ViewInterface public class ArticleViewModel extends ViewModel<Article> implements PageEntryView { public String getHeadline() { return model.title + "!!!"; } public FooViewModel getFoo() { return this.createView(FooViewModel.class, new Foo()); } } @ViewInterface public class FooViewModel extends ViewModel<Foo> { public String getBar() { return "Baz"; } }
Generated Schema
type Query { PageEntryView(id: ID, path: String): PageEntryView ArticleViewModel(id: ID, path: String): ArticleViewModel } union com_psddev_cms_view_PageEntryView = ArticleViewModel type ArticleViewModel { _modelId: ID _modelType: ID headline: String foo: FooViewModel } type FooViewModel { bar: String }
Example Query
query SimpleViewModelExample { PageEntryView(path: "/article-example") { __type ... on ArticleViewModel { _modelId _modelType headline foo { bar } } } }
Sample Response
{ "data": { "PageEntryView": { "__typename": "ArticleViewModel", "_modelId": "99157c6c-224f-42e9-b5c9-3ad8b40e16cc", "_modelType": "0000015d-56b9-d2db-a5dd-f6fd6ecb0003", "headline": "Article Example!!!", "foo": { "__typename": "FooViewModel", "bar": "Baz" } } } }
In the above example, a query API was not generated for FooViewModel
because the backing model class Foo
is not Recordable
. There were also no _model*
fields generated in the FooViewModel
schema type for the same reason.