How to add a custom property in Optimizely Graph

In the Optimizely CMS content can be synchronized to the Optimizely Graph service for it then to be exposed by the GraphQL API. In some cases, you may want to add or adjust a property when the content is being synchronized.

An example of this is when media files have a file size property that represents the file size as the number of bytes. The UI that displays this information will need to format the bytes (e.g. 10000000) into a readable string such as 10MB. The server can take on this responsibility by adding another property to the Graph schema that will display the formatted string, which ensures consistency across the applications that require the formatted file size.

The code below will add a custom API model property to the Graph schema called FileSizeFormatted, which uses the GetValue method to get the FileSize property and format it to a readable string using the custom extension method ToFormattedString().

[ServiceConfiguration(typeof(IContentApiModelProperty), Lifecycle = ServiceInstanceScope.Singleton)]
public class FileSizeContentApiModelProperty : IContentApiModelProperty
{
    //To override an existing property you can use the same name.
    public string Name => "FileSizeFormatted";

    public object GetValue(ContentApiModel contentApiModel)
    {
        //Validate that the model contains a FileSize property
        //Another option is to validate the content type
        if (!contentApiModel.Properties.TryGetValue("FileSize", out var property))
            return string.Empty;

        if (int.TryParse(property.ToString(), out var fileSize))
            return fileSize.ToFormattedString(); //Custom extension method

        return string.Empty;
    }
}

Then after running the content synchronization scheduled job, the GraphQL schema and content has been updated with the new property.

Query

{
  PdfFile(limit: 100) {
    items {
       FileSize
       FileSizeFormatted
    }
  }
}

Result

{
  "data": {
    "PdfFile": {
      "items": [
        {
          "FileSize": 2107621,
          "FileSizeFormatted": "2mb"
        },
        {
          "FileSize": 1070229,
          "FileSizeFormatted": "1045kb"
        }
      ]
    }
  }
}

This is a basic example of creating a custom API model property, and there is room for improvement, because any custom property is added to all schema types. It's still early days for Optimizely Graph, so we can expect that property customization will be improved in the future.