Jake Minard
Oct 15, 2024
  857
(3 votes)

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.

Oct 15, 2024

Comments

Please login to comment.
Latest blogs
Increase timeout for long running SQL queries using SQL addon

Learn how to increase the timeout for long running SQL queries using the SQL addon.

Tomas Hensrud Gulla | Dec 20, 2024 | Syndicated blog

Overriding the help text for the Name property in Optimizely CMS

I recently received a question about how to override the Help text for the built-in Name property in Optimizely CMS, so I decided to document my...

Tomas Hensrud Gulla | Dec 20, 2024 | Syndicated blog

Resize Images on the Fly with Optimizely DXP's New CDN Feature

With the latest release, you can now resize images on demand using the Content Delivery Network (CDN). This means no more storing multiple versions...

Satata Satez | Dec 19, 2024

Simplify Optimizely CMS Configuration with JSON Schema

Optimizely CMS is a powerful and versatile platform for content management, offering extensive configuration options that allow developers to...

Hieu Nguyen | Dec 19, 2024

Useful Optimizely CMS Web Components

A list of useful Optimizely CMS components that can be used in add-ons.

Bartosz Sekula | Dec 18, 2024 | Syndicated blog

SaaS CMS - Pages and Blocks get the Visual Builder Treatment

I’m thrilled to see that Optimizely has now enabled Visual Builder for OG Pages and Blocks within SaaS CMS, and I’m guessing this will become...

Minesh Shah (Netcel) | Dec 17, 2024