Introducing Optimizely Graph Source .NET SDK
Overview Of Optimizely Graph
Optimizely Graph is a cutting-edge, headless content management solution designed to integrate seamlessly with any application. It empowers developers to access, manipulate, and query content through a unified graph structure using GraphQL. This approach allows for efficient, flexible content delivery across multiple platforms.
With its dynamic capabilities, Optimizely Graph is ideal for content-driven applications where performance and flexibility are critical. It significantly enhances searchability and delivery, offering a robust foundation for enterprise-level digital experiences.
What Does The SDK Offer?
The new Optimizely Graph SDK takes the platform’s power to the next level by simplifying configuration and setup. This repository abstracts away the complexity of underlying API requests, allowing developers to configure content types, build data, and sync content with Optimizely Graph — all with minimal effort in C#.
The SDK is designed for easy integration into any .NET backend application. It empowers developers to push their data from external sources, allowing for a flexible content management process tailored to specific business needs.
How Does It Work?
Getting started with the Optimizely Graph SDK is straightforward. First, initialize a new instance of the GraphSourceClient by invoking the static Create
method. You'll need to pass in the base URL, source, application key, and secret, as shown below:
var client = GraphSourceClient.Create( new Uri("https://cg.optimizely.com"), "source", "application-key", "secret" );
Once initialized, you can configure content types using any C# class object. This seamless integration allows you to manage your content directly within your existing application’s codebase.
For example, imagine a café that needs to configure content for its menu. With the Optimizely Graph SDK, you can model the menu’s structure using C# classes, making the process efficient and intuitive. Here’s a sample class definition for a café:
public class Cafe { public string Name { get; set; } public DateTime Established { get; set; } public Location Address { get; set; } public Menu Menu { get; set; } } public class Location { public string City { get; set; } public string State { get; set; } public string Zipcode { get; set; } public string Country { get; set; } } public class Menu { public Beverage Beverage { get; set; } public Food Food { get; set; } } public class Beverage { public string Name { get; set; } public double Price { get; set; } public List<string> Sizes { get; set; } } public class Food { public string Name { get; set; } public double Price { get; set; } public bool IsAvaiable { get; set; } }
In the C# object example above, we demonstrated how you can represent multiple data types, class types, and nested types, all of which can be effortlessly configured with Optimizely Graph. This flexibility allows you to model complex content structures directly within your application.
By abstracting the complexity of setup and configuration, the SDK empowers developers to focus on building dynamic, high-performance applications without getting bogged down in the details of data management.
Configuring Content Types
Now, let’s take it a step further and use the client we initialized earlier to configure these types in Optimizely Graph. With just a few lines of code, you can map and configure your content to be indexed efficiently.
client.ConfigureContentType<Cafe>() .Field(x => x.Name, IndexingType.Queryable) .Field(x => x.Established, IndexingType.Searchable) .Field(x => x.Address, IndexingType.PropertyType) .Field(x => x.Menu, IndexingType.PropertyType); client.ConfigurePropertyType<Location>() .Field(x => x.City, IndexingType.Queryable) .Field(x => x.State, IndexingType.Queryable) .Field(x => x.Zipcode, IndexingType.Searchable) .Field(x => x.Country, IndexingType.Searchable); client.ConfigurePropertyType<Menu>() .Field(x => x.Beverage, IndexingType.PropertyType) .Field(x => x.Food, IndexingType.PropertyType); client.ConfigurePropertyType<Beverage>() .Field(x => x.Name, IndexingType.Queryable) .Field(x => x.Price, IndexingType.Queryable) .Field(x => x.Sizes, IndexingType.Searchable); client.ConfigurePropertyType<Food>() .Field(x => x.Name, IndexingType.Queryable) .Field(x => x.Price, IndexingType.Queryable) .Field(x => x.IsAvaiable, IndexingType.Searchable);
Explaining Index Types
In the example above, we’ve used several index types: PropertyType, Searchable, and Queryable. Understanding these types is crucial for optimizing how Optimizely Graph indexes your content fields.
- PropertyType is used for nested data objects within your content structure.
- Queryable allows filtering, ordering, and faceting by specific fields, with support for the “contains” operator.
- Searchable enables full-text and semantic search using vectorized fields, with support for the “match” operator, ordering, and faceting.
These indexing options help you configure your content for faster reads and more precise queries.
Saving Content Types
Before saving your content types, it’s important to set your preferred language. In this example, we’re using English:
client.AddLanguage("en");
Now you can use the initialized client to save your content types. The SDK handles building the request on the backend and interacts with Optimizely Graph on your behalf.
await client.SaveTypesAsync();
Once this step is complete, you can visit the Graph UI to view and query your configured types.
The Graph UI provides documentation on your content types and offers helpful tips for building GraphQL queries.
Synchronizing Your Data
It’s time to sync your content! To do this, simply create an instance of your class object and pass it into the client. Here’s an example using the Cafe
class:
var exampleDataInstance1 = new Cafe { Name = "Optimizely's Awesome Cafe", Established = new DateTime(2024, 06, 12), Address = new Location { City = "New York", State = "NY", Zipcode = "10003", Country = "USA" }, Menu = new Menu { Beverages = new List<Beverage> { new() { Name = "Espresso", Price = 4.99, Sizes = new[] { "S", "M" } }, new() { Name = "Latte", Price = 5.99, Sizes = new[] { "M", "L" } }, new() { Name = "Cappuccino", Price = 6.99, Sizes = new[] { "S", "M", "L" } } }, Food = new List<FoodItem> { new() { Name = "Bagel", Price = 5.25, IsAvaiable = true }, new() { Name = "Croissant", Price = 3.89, IsAvaiable = true }, new() { Name = "Cinnamon Roll", Price = 4.99, IsAvaiable = false } } } };
To push your content to Optimizely Graph, you’ll need to assign a unique ID to each data instance.
In the following example, we’ll use the café name and city to generate a unique ID. This ID is crucial for identifying and updating content later. If content with the same ID is pushed again, it will be overwritten.
Use the SaveContentAsync
method to push your content:
await client.SaveContentAsync( generateId: (x) => $"{x.Name}_{x.Address.City}", exampleDataInstance1 );
The SDK also supports pushing multiple objects at once by passing an array of data. The example below shows this with a comma separated parameter list.
await client.SaveContentAsync( generateId: (x) => Guid.NewGuid().ToString(), exampleDataInstance1, exampleDataInstance2, etc... );
What’s Next?
That’s it! You’ve successfully configured your content types and synced your data with Optimizely Graph.
Now you can revisit the Graph UI and run queries to retrieve your data. Here’s an example of what your query and response might look like:
One of the great benefits of Optimizely Graph is the flexibility it offers through GraphQL. You can construct queries to meet your exact business needs, taking full advantage of a powerful Elasticsearch backend to query data efficiently.
Flexibility With GraphQL
GraphQL provides the flexibility to filter and refine your results, enabling efficient and targeted content management. You can leverage any GraphQL query parameter to ensure that content retrieval is both precise and effective.
As your content grows — like adding more cafes with unique menus — you can easily query your data using any field or nested field that was configured during setup. For instance, to find the name of a café in Stockholm that serves espresso, you can write a GraphQL query like this:
{ Cafe(locale: en, where: {Address: {City: {eq: "Stockholm"}}, _and: {Menu: {Beverages: {Name: {eq: "Espresso"}}}}}){ items{ Name } } }
This flexibility allows you to create highly specific queries, ensuring your application gets exactly the data it needs with minimal overhead.
Conclusion
The Optimizely Graph Source .NET SDK simplifies and accelerates the process of integrating with Optimizely Graph. By abstracting the complexity of API requests and streamlining content type configuration, it enables developers to focus on building high-performance applications.
With future plans to extend this SDK into other tech stacks, Optimizely continues to make content management more accessible and provide simpler solutions for developers.
The Graph Source SDK code repository is open source, with ongoing development and improvements, and further plans to convert it into a NuGet package.
Comments