Build an ASP.NET Core API (manual GraphQL client)
Learn how to build an ASP.NET Core Web API that retrieves content from Optimizely Graph using a lightweight manual GraphQL client.
This guide shows how to build an ASP.NET Core Web API that connects to Optimizely Graph, queries content with GraphQL, and exposes the results through REST endpoints. Use the manual GraphQL client approach when you want a lightweight integration and full control over query strings and response models.
The manual client approach fits the following scenarios:
- Small or experimental projects.
- Learning how GraphQL requests and responses work.
- Projects that need full control over queries and models.
For automatic code generation, strong typing, and compile-time validation, see Build an ASP.NET Core API with StrawberryShake instead.
Create an ASP.NET Core project
Scaffold a Web API project that hosts the controllers and GraphQL client wiring used throughout this guide.
dotnet new webapi -n MyOptimizelyApp
cd MyOptimizelyAppInstall dependencies
Add the GraphQL HTTP client packages that send queries to Optimizely Graph and deserialize the JSON responses.
dotnet add package GraphQL.Client
dotnet add package GraphQL.Client.Serializer.Newtonsoft
dotnet add package Microsoft.Extensions.Options.ConfigurationExtensionsCreate GraphQL schema and queries
Download the schema and author the queries the controller sends to Optimizely Graph. The examples below target the Alloy template content types.
# Download schema
dotnet graphql download https://cg.optimizely.com/content/v2?auth=YOUR_ACCESS_KEY -f schema.graphqlUse the following query to retrieve a list of articles from the database.
query GetArticles($limit: Int = 10, $skip: Int = 0) {
ArticlePage(
orderBy: { _modified: DESC }
limit: $limit
skip: $skip
) {
items {
ContentLink {
Id
}
Name
RelativePath
TeaserText
PageImage {
Url
}
MainBody
}
total
}
}
query GetArticleById($id: String!) {
ArticlePage(
where: { ContentLink: { Id: { eq: $id } } }
) {
items {
ContentLink {
Id
}
Name
RelativePath
TeaserText
PageImage {
Url
}
MainBody
_modified
}
}
}
Configure the GraphQL client
Configure the GraphQL client so the controller can resolve a typed HTTP client at runtime and send queries to Optimizely Graph.
Create a .graphqlrc.json configuration file.
{
"schema": "schema.graphql",
"documents": "Queries/**/*.graphql",
"extensions": {
"strawberryShake": {
"name": "OptimizelyGraphClient",
"namespace": "MyOptimizelyApp.GraphQL",
"url": "https://cg.optimizely.com/content/v2?auth=YOUR_KEY"
}
}
}Register the GraphQL client in Program.cs.
using GraphQL.Client.Http;
using GraphQL.Client.Serializer.Newtonsoft;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<GraphQLHttpClient>(provider =>
{
return new GraphQLHttpClient(
"https://cg.optimizely.com/content/v2?auth=YOUR_KEY",
new NewtonsoftJsonSerializer()
);
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseRouting();
app.MapControllers();
app.Run();Store the endpoint in configuration (optional)
Move the Optimizely Graph endpoint out of code into appsettings.json so environments override the value without recompiling.
{
"OptimizelyGraph": {
"Endpoint": "https://cg.optimizely.com/content/v2?auth=YOUR_KEY"
}
}Create the response model
Define C# classes that mirror the GraphQL response shape so the deserializer maps fields onto strongly typed objects.
public class Article
{
public ContentLink ContentLink { get; set; }
public string Name { get; set; }
public string RelativePath { get; set; }
public string TeaserText { get; set; }
public MediaReference PageImage { get; set; }
public string MainBody { get; set; }
}
public class ContentLink { public string Id { get; set; } }
public class MediaReference { public string Url { get; set; } }
public class ContentResponse
{
public List<Article> Items { get; set; } = new();
public int Total { get; set; }
}
public class GraphQLResponse<T>
{
public T ArticlePage { get; set; }
}Create a controller
Expose the Optimizely Graph data through an ASP.NET Core controller that sends GraphQL queries with the manual client and returns the results from REST endpoints.
Create Controllers/ArticlesController.cs.
using GraphQL;
using GraphQL.Client.Http;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class ArticlesController : ControllerBase
{
private readonly GraphQLHttpClient _graphQLClient;
public ArticlesController(GraphQLHttpClient graphQLClient)
{
_graphQLClient = graphQLClient;
}
[HttpGet]
public async Task<ActionResult> GetArticles()
{
var query = @"
query {
ArticlePage(orderBy: { _modified: DESC }, limit: 10) {
items {
ContentLink { Id }
Name
RelativePath
TeaserText
PageImage { Url }
MainBody
}
total
}
}";
var request = new GraphQLRequest { Query = query };
var response =
await _graphQLClient.SendQueryAsync<GraphQLResponse<ContentResponse>>(request);
if (response.Errors?.Any() == true)
{
return BadRequest(response.Errors);
}
return Ok(response.Data.ArticlePage);
}
}Run and test the API
Build and run the application to confirm the controller resolves the GraphQL client and returns content from Optimizely Graph.
dotnet build
dotnet runTest the API endpoint
Send a request to the controller route to verify the round trip between the API, the manual GraphQL client, and Optimizely Graph.
Use the https://localhost:7000/api/articles endpoint to test the API and confirm it returns content from Optimizely Graph.
Updated 10 days ago
