Synchronize content types
With custom content sources, you can add custom data to Optimizely Graph and query using the GraphQL API.
Optimizely Graph provides endpoints to let you define the GraphQL schema of your content source. The schema is important for the data you upload to the Optimizely Graph service.
Important
This feature is not enabled by default for your account. Contact Optimizely with a request to get additional sources.
Synchronize full content definition
Note
The schema does not work if several content types have the same name across sources. You must have unique names on the content types from external sources that do not conflict with content types in CMS.
For information, refer to the Full content type update API reference.
The full content type
API endpoint lets you sync the full definition of your content to the service.
curl --location --request PUT 'https://dev.cg.optimizely.com/api/content/v3/types?id=MyNewSource' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic V25KQmNtUlpSNTFYaDJuSmE345UWV5eEkwWWxOUVpFhjkdWsxMDRWV1BYZkcydlcxZUluOlduSkJjbVJaUjUxWGgybkphNVFleXhJMFlsTlFaRXVrMTA0VldQWGZHMnZXMWVJbg==' \
--data '{
"languages": ["en"],
"contentTypes":{
"test": {
"contentType": [],
"properties": {
"Name": {
"type": "String"
}
}
}
}
}
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Put, "https://dev.cg.optimizely.com/api/content/v3/types?id=,quang");
request.Headers.Add("Authorization", "Basic V25KQmNtUlpSNTFYaDJuSmEghjU0WdgV5eEkwWWxOUVpFdWsxMDRWV1BYZkcydlcxZUluOlduSkJjbVJaUjUxWGgybkphNVFleXhJMFlsTlFaRXVrMTA0VldQWGZHMnZXMWVJbg==");
var content = new StringContent("{\n \"languages\": [\"en\"],\n \"contentTypes\":{\n \"test\": {\n \"contentType\": [],\n \"properties\": {\n \"Name\": {\n \"type\": \"String\"\n }\n }\n }\n }\n}", null, "application/json");
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
id=MyNewSource
– Source name.languages
– Required and not empty.contentTypes
– Required and not empty.test
– Content type name.contentType
– Required.properties
– Required and not empty.
The above request creates a MyNewSource
datasource and a GraphQL schema that matches the content type.
Important
If you upload a full content definition using the
full content type
API endpoint, all data in the content source is deleted.
Example
The following example shows how to define property types, languages, and content types for a content source containing product information. It shows the use of simple data types in addition to the ProductLanguage
property type.
{
"propertyTypes": {
"ProductLanguage": {
"properties": {
"DisplayName": {
"name": "DisplayName",
"type": "String"
},
"Name": {
"name": "Name",
"type": "String"
}
}
}
},
"label": "Commerce",
"languages": [
"en"
],
"contentTypes": {
"Catalog": {
"abstract": true,
"contentType": [],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String"
}
}
},
"Product": {
"contentType": [
"Catalog"
],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String"
},
"Language":{
"type": "ProductLanguage"
},
"Quantity": {
"type": "Int"
},
"Size": {
"type": "Float"
},
"Color": {
"type": "String"
}
}
}
}
}
The following curl
command issues a PUT
request with the definition using the ID com
, which is the name of the content source. If the content source does not exist already, it is created.
Important
If you create more content sources than your account lets you, the call will fail, and the content source will not be created.
curl --location --request PUT 'https://cg.optimizely.com/api/content/v3/types?id=com' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic V25KQmNtUlpSNTFYaDJuSmE1UWV5eEkwWWxOUVpFdWsxMDRWV1BYZkcydlcxZUluOkYwaWRhcDRPQ1ZOc0JSQTJmdVpCVDNtYXVoaVl1QWtRcDM5SHduazB2dW1XblpoZytjbmg4QnpHVU5VQlVIYTM=' \
--data '{
"propertyTypes": {
"ProductLanguage": {
"properties": {
"DisplayName": {
"name": "DisplayName",
"type": "String"
},
"Name": {
"name": "Name",
"type": "String"
}
}
}
},
"label": "Commerce",
"languages": [
"sv"
],
"contentTypes": {
"Catalog": {
"abstract": true,
"contentType": [],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String"
}
}
},
"Product": {
"contentType": [
"Catalog"
],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String"
},
"Language":{
"type": "ProductLanguage"
},
"Quantity": {
"type": "Int"
},
"Size": {
"type": "Float"
},
"Color": {
"type": "String"
}
}
}
}
}'
Authorization
The acceptable authorization is Basic
and epi-hmac
:
Basic
:
- Username – AppKey
- Password – Secret
Both the username and password must be encoded by the base64 algorithm, so the header is Authorization: Basic base64(AppKey:Secret)
.
epi-hmac
– The AppKey and the Secret are signed by the hmac algorithm.
var crypto = require("crypto-js");
var sdk = require('postman-collection');
// This script uses 2 variables.
//
// EPTSKey
// EPTSSecret
//
var method = pm.request.method;
var key = pm.variables.get("EPTSKey");
var secret = CryptoJS.enc.Base64.parse(pm.variables.get("EPTSSecret"));
var target = new sdk.Url(request.url).getPathWithQuery();
var timestamp = (new Date()).getTime();
var nonce = Math.random().toString(36).substring(7);
var body = "";
if( pm.request.body )
{
body = pm.request.body.raw;
}
var bodybase64 = crypto.MD5(body).toString(CryptoJS.enc.Base64);
var hmac = crypto.HmacSHA256(key + method + target + timestamp + nonce + bodybase64, secret);
var base64hmac = CryptoJS.enc.Base64.stringify(hmac);
var header = "epi-hmac " + key + ":" + timestamp +":" + nonce + ":" + base64hmac;
pm.request.headers.add(header, "Authorization")
Synchronize partial content type
Note
Refer to the API Reference on Partial content type update for information.
You must call synchronize full content type before using this endpoint to update partial content type.
The Partial content type
endpoint lets you sync the partial content type to the service.
Example
The following example changes the Name
to be searchable by adding searchable
to the Name
property :
"Name": { "type": "String", "searchable": true }
{
"languages": [
"en"
],
"contentTypes": {
"Product": {
"contentType": [
"Catalog"
],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String",
"searchable": true
},
"Language":{
"type": "ProductLanguage"
},
"Quantity": {
"type": "Int"
},
"Size": {
"type": "Float"
},
"Color": {
"type": "String"
}
}
}
}
}
Again, the data is being sent to the types
endpoint but using POST
instead of PUT
. It uses the com
ID to specify the target content source.
curl --location 'https://cg.optimizely.com/api/content/v3/types?id=com' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic V25KQmNtUlpSNTFYaDJuSmE1UWV5eEkwWWxOUVpFdWsxMDRWV1BYZkcydlcxZUluOkYwaWRhcDRPQ1ZOc0JSQTJmdVpCVDNtYXVoaVl1QWtRcDM5SHduazB2dW1XblpoZytjbmg4QnpHVU5VQlVIYTM=' \
--data '{
"languages": [
"en"
],
"contentTypes": {
"Product": {
"contentType": [
"Catalog"
],
"properties": {
"Id": {
"type": "String"
},
"Name": {
"type": "String",
"searchable": true
},
"Language":{
"type": "ProductLanguage"
},
"Quantity": {
"type": "Int"
},
"Size": {
"type": "Float"
},
"Color": {
"type": "String"
}
}
}
}
}'
Updated 5 months ago