Deserialize Content Management API
Describes the deserialization process in Optimizely Content Management API and how to customize it.
When receiving a request, the Optimizely Content Management API first deserializes the data from the request body into models and then handles the request.
The Content Management API defines some input models (ContentApiCreateModel
, ContentApiPatchModel
), which plays a role as data transform objects for deserialization. Data is transformed into those models before being converted to IContent
and saved to the database. For example, the diagram below illustrates the scenario of creating a content item.
The workflow follows the following steps:
- You request to Post a content endpoint with an input model in JSON format.
- The server accepts the request and transforms the JSON data into
ContentApiCreateModel
. Some metadata fields are mapped automatically, and the custom properties are converted toPropertyModel
. - Before saving the content, the
ContentApiCreateModel
is migrated to theIContent
. The list ofPropertyModel
is converted to thePropertyData
, then added to theIContent.Property
.
The flow is the same for all endpoints.
Customize the deserialization
If you define a custom PropertyData
in your model, you need to register a custom PropertyModel
and a custom converter to determine which PropertyData
corresponds to which PropertyModel
. For example, you have a custom property PropertyStringList, which inherits the PropertyLongString
:
[EditorHint(Global.SiteUIHints.Strings)]
[PropertyDefinitionTypePlugIn(Description = "A property for list of strings", DisplayName = "String List")]
public class PropertyStringList: PropertyLongString {
protected String Separator = "\n";
public String[] List {
get {
return (String[]) Value;
}
}
public override Type PropertyValueType {
get {
return typeof (String[]);
}
}
public override object SaveData(PropertyDataCollection properties) {
return LongString;
}
public override object Value {
get {
var value = base.Value as string;
if (value == null) {
return null;
}
return value.Split(Separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
}
set {
if (value is String[]) {
var s = String.Join(Separator, value as String[]);
base.Value = s;
} else {
base.Value = value;
}
}
}
}
For Content Management API to handle this custom property, you need to register a corresponding StringListPropertyModel
:
public class StringListPropertyModel: PropertyModel<IList<string>, PropertyStringList> {
[JsonConstructor]
internal StringListPropertyModel(): this(new PropertyStringList()) {}
public StringListPropertyModel(PropertyStringList propertyStringList): base(propertyStringList) {
Value = propertyStringList.List;
}
}
And a StringListPropertyDataValueConverter
that implements the IPropertyDataValueConverter
:
[ServiceConfiguration(typeof (IPropertyDataValueConverter))]
[PropertyDataValueConverter(new Type[] {
typeof (StringListPropertyModel)
})]
internal class StringListPropertyDataValueConverter: IPropertyDataValueConverter {
///<inheritdoc />
public object Convert(IPropertyModel propertyModel, PropertyData propertyData) {
if (propertyModel is null) {
throw new ArgumentNullException(nameof(propertyModel));
}
return ((StringListPropertyModel) propertyModel).Value;
}
}
Data format
Flatten configuration controls whether the deserialized representation of properties should only include the value of all properties rather than both value and property type (for POST, PUT, or PATCH requests). This should be carefully noted because it impacts the data format sent to endpoints.
For information about the flattened model, see Flatten.
Updated 6 months ago