Customize data returned to clients
Describes how to customize data returned to clients in the Optimizely Content Delivery API.
The following approaches customize how response data is returned for requests.
- Use Select parameter in endpoints.
- Use
IContentFilter
andIContentApiModelFilter
. - Use
IPropertyConverter
andIPropertyConverterProvider
to convert fromIContent
toContentApiModel
. This approach is not addressed in this article.
(1) and (2) are described below, respectively, while (3) is addressed in Customize conversion from IContent to ContentApiModel.
Select parameter in endpoints
Endpoints in Content Delivery API let you filter data returned to requests by using the select
parameter.
Assign the property names expected in the response to the parameter, separated by a comma. The value of this parameter is extracted and passed to ConverterContext.SelectedProperties
for later use.
The following image shows an example with a Get
endpoint, but the result format is the same for others also. For endpoints related to GetChildren
and GetAncestor
, data filtering is applied for each item returned to clients. Property names are not case-sensitive, and contentLink, name, and language are returned regardless of parameter value.
This feature cannot be applied to expanded values. Where clients send a request and expect properties to be expanded, the expanded value still shows full data without filtering it according to select
. The following image shows this. Although some properties are passed in param, the expanded value pageImage
still shows full data as normal.
Use IContentFilter and IContentApiModelFilter
Although IContentFIlter
and IContentApiModelFilter
was marked as Preview for safety purposes; they were stable and worth being used for customization. The preview may be removed in a coming .NET Core version of Content Delivery API.
The following diagram shows how IContent
is converted into ContentAPIModel
, which is then serialized and returned to clients. The select
parameter in the request (described in Select
parameter in endpoints) is extracted and passed to ConverterContext
. It is then used by ContentApiModelMinifier
to filter data.
This section focuses on two other ways to filter data with IContentFilter
and IContentApiModelFilter
.
IContentFilter
The IContent Filtering phase takes responsibility to filter IContent
data before it is converted to ContentApiModel
. Within this phase, the IContent
properties can be filtered according to specific rules. The following code sample shows an example of how to filter data using IContentFilter
. The filter impactsExpandedValue
also.
[ServiceConfiguration(typeof (IContentFilter), Lifecycle = ServiceInstanceScope.Singleton)]
internal class CustomContentFilter: ContentFilter<IContent> {
public override void Filter(IContent content, ConverterContext converterContext) {
content.Property.Remove("PageImage");
content.Property.Remove("MainContentArea");
}
}
The code sample is simple, but you can use other services or HttpContext
to do more filtering within the class (for example, pass some parameters in the request and extract them by using HttpContext
or injected services for more data manipulation).
With the previous code example, the properties PageImage
and MainContentArea
are removed from IContent
, meaning that they will not display in the conversion phase later. As a result, they will disappear in the result returned to clients. The downside of IContentFilter
is that it is still not possible to remove some default properties of ContentApiModel
like ExistingLanguages
, MasterLanguage
, and so on.
Note
Some properties are mandatory (such as,
PageLink
andPageTypeID
, if content is a page) and those should not be removed in the filter. Otherwise, exceptions are thrown in the conversion phase later on.
IContentApiModelFilter
After IContent
is converted to ContentApiModel
, and before data is returned to clients (or minified based on a select parameter), you can filter the ContentApiModel
data in the ContentApiModel
filtering phase, as shown in the following code sample. The sample uses the select
parameter.
[ServiceConfiguration(typeof (IContentApiModelFilter), Lifecycle = ServiceInstanceScope.Singleton)]
internal class CustomContentApiModelFilter: ContentApiModelFilter<ContentApiModel> {
public override void Filter(ContentApiModel contentApiModel, ConverterContext converterContext) {
// Select param mentioned in the first part of article is retrieved and passed to ConverterContext.SelectedProperties
// but it's only for the parent content. In case that clients contain child content that can be expanded, the param value is not served for them.
// so that we need to extract param like the following if we want to apply select param for child elements.
var selectedParamValue = string.Empty;
if (HttpContext.Current.Request.QueryString["select"] == null) {
return;
}
selectedParamValue = HttpContext.Current.Request.QueryString["select"].ToString();
var selectedProperties = string.IsNullOrWhiteSpace(selectedParamValue) ? new HashSet<string>() : new HashSet<string>(selectedParamValue.Split(',').Select(x => x.Trim()), StringComparer.OrdinalIgnoreCase);
try {
var dictProp = new Dictionary<string, object>();
contentApiModel.Properties = contentApiModel.Properties.Where(entry => selectedProperties.Contains(entry.Key))
.ToDictionary(entry => entry.Key, entry => entry.Value);
// Set those values below as null, and configure ContentApiOption.IncludeNullValues = false in Initialization
// then, response data will not include those ones.
contentApiModel.ExistingLanguages = null;
contentApiModel.MasterLanguage = null;
contentApiModel.ParentLink = null;
contentApiModel.Language = null;
contentApiModel.StartPublish = null;
contentApiModel.StopPublish = null;
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
}
As in the previous example, IContentApiModelFilter
lets you remove the default ContentApiModel
properties and filter data returned by using select parameters. The filter is activated each time an IContent
is converted to ContentApiModel
. This means it affects nested elements or items in ContentArea
in an expanded scenario, which also makes the response body much cleaner and lighter. ContentApiOption.IncludeNullValue
should be set to false in the configuration for this sample.
Note
In a case where the whole conversion phase should be customized for a specific reason, you can use
ContentConvertingService
(a public service) to fulfill the requirement. However, this is not recommended due to the complexity to handleIContent
.
Updated 6 months ago