Appearance
Are you an LLM? You can read better optimized documentation at /configuration/api_configuration.md for this page in Markdown format
API configuration
This document provides a detailed technical overview of the configuration for the Contentful API client within TheExampleApp. It covers the static configuration from appsettings.json, the dynamic runtime override mechanism, and the logic for selecting between the Delivery and Preview APIs.
ContentfulOptions
The core of the Contentful integration is managed through the ContentfulOptions class, provided by the Contentful.Core.Configuration namespace. This object encapsulates all necessary credentials and settings required by the ContentfulClient to communicate with the Contentful APIs.
The application's base configuration is loaded from the appsettings.json file. The AddContentful extension method, called during application startup, binds the ContentfulOptions section of the configuration file to the ContentfulOptions class and registers it in the dependency injection (DI) container.
TheExampleApp/Startup.cs
csharp
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddContentful(Configuration);
// ...
}1
2
3
4
5
6
7
2
3
4
5
6
7
The ContentfulOptions section in appsettings.json looks like this:
TheExampleApp/appsettings.json
json
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"ContentfulOptions": {
"DeliveryApiKey": "df2a18b8a5b4426741408fc95fa4331c7388d502318c44a5b22b167c3c1b1d03",
"PreviewApiKey": "10145c6d864960fdca694014ae5e7bdaa7de514a1b5d7fd8bd24027f90c49bbc",
"SpaceId": "qz0n5cdakyl9",
"UsePreviewApi": false
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
For more information on the initial setup, refer to the Contentful Setup documentation.
Configuration properties
The ContentfulOptions class contains several properties that control the behavior of the API client. The following are the most critical for this application:
| Property | Type | Description |
|---|---|---|
SpaceId | string | The unique identifier for your Contentful space. This is mandatory for all API requests. |
DeliveryApiKey | string | The API key for the Content Delivery API (CDA). This key provides read-only access to published content and is safe for client-side/public use. |
PreviewApiKey | string | The API key for the Content Preview API (CPA). This key provides access to both draft and published content. It should be kept secret. |
UsePreviewApi | boolean | A flag that instructs the ContentfulClient which API to target. If true, the client uses the Preview API and the PreviewApiKey. If false, it uses the Delivery API and the DeliveryApiKey. |
These properties are initially set from appsettings.json but can be overridden at runtime, as detailed in the next section. See the Application Settings documentation for more on base configuration.
Runtime configuration changes
A key feature of this application is the ability for a user to change the Contentful API credentials at runtime via the /settings page. This is particularly useful for development and testing, allowing developers to switch between different Contentful spaces or toggle preview mode without a code change or application restart.
This functionality is achieved through a custom implementation that overrides the default Contentful options with values stored in the user's session.
ContentfulOptionsManager Implementation
To manage the dynamic configuration, the application implements a custom IContentfulOptionsManager. This class is responsible for deciding whether to use the base configuration from appsettings.json or a temporary configuration from the current user's session.
TheExampleApp/Configuration/ContentfulOptionsManager.cs
csharp
/// <summary>
/// Class used to configure whether the current session should use the application configuration or options from session.
/// This to allow injecting different credentials at runtime.
/// </summary>
public class ContentfulOptionsManager : IContentfulOptionsManager
{
private ContentfulOptions _options;
private readonly IHttpContextAccessor _accessor;
public ContentfulOptionsManager(IOptions<ContentfulOptions> options, IHttpContextAccessor accessor)
{
_options = options.Value;
_accessor = accessor;
}
/// <summary>
/// Gets the currently configured <see cref="ContentfulOptions"/> either from session, if present, or from the application configuration.
/// </summary>
public ContentfulOptions Options
{
get
{
var sessionString = _accessor.HttpContext.Session.GetString(nameof(ContentfulOptions));
if (!string.IsNullOrEmpty(sessionString))
{
return JsonConvert.DeserializeObject<ContentfulOptions>(sessionString);
}
return _options;
}
}
// ...
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
The logic is straightforward:
- It attempts to retrieve a JSON string from the session with the key
ContentfulOptions. - If the string exists, it is deserialized into a
ContentfulOptionsobject and returned. - If no value is found in the session, it returns the default
_optionsthat were injected fromappsettings.jsonat startup.
The ContentfulOptionsManager also exposes an IsUsingCustomCredentials property that indicates whether the current session is using credentials different from the base application configuration. It compares the session-stored options (if present) against the default _options for SpaceId, UsePreviewApi, DeliveryApiKey, and PreviewApiKey. If any of these values differ, the property returns true, indicating custom credentials are in use.
Session-based Credential Override
The ContentfulOptionsManager is registered as a singleton in the DI container. Crucially, the application also provides a custom factory for IContentfulClient to ensure it always uses the options provided by our custom manager.
TheExampleApp/Startup.cs
csharp
// This would normally not be needed, but since we want to load our ContentfulOptions from memory if they're changed within the application
// we provide our own implementation logic for the IContentfulClient
services.AddSingleton<IContentfulOptionsManager, ContentfulOptionsManager>();
services.AddTransient<IContentfulClient, ContentfulClient>((ip) => {
var client = ip.GetService<HttpClient>();
var options = ip.GetService<IContentfulOptionsManager>().Options;
var contentfulClient = new ContentfulClient(client,
options);
var version = typeof(Startup).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion;
contentfulClient.Application = $"app the-example-app.csharp/{version}; {contentfulClient.Application}";
return contentfulClient;
});1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
This registration ensures that on every request where an IContentfulClient is resolved, it is instantiated with the potentially session-overridden ContentfulOptions.
Settings Page Functionality
The /settings page provides the UI for this feature. The SettingsModel page model handles the logic for updating and persisting the new options to the session.
When a user submits new credentials, the OnPost handler serializes a new ContentfulOptions object and saves it to the session.
TheExampleApp/Pages/Settings.cshtml.cs
csharp
public IActionResult OnPost(SelectedOptions appOptions)
{
if (!ModelState.IsValid)
{
// ... handle validation
return Page();
}
// ...
var currentOptions = new ContentfulOptions
{
DeliveryApiKey = appOptions.AccessToken,
SpaceId = appOptions.SpaceId,
UsePreviewApi = _manager.Options.UsePreviewApi,
PreviewApiKey = appOptions.PreviewToken,
// ... other properties are retained
};
// The new options are serialized and stored in the session.
HttpContext.Session.SetString(nameof(ContentfulOptions), JsonConvert.SerializeObject(currentOptions));
TempData["Success"] = true;
return RedirectToPage("Settings");
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
The page also includes robust validation within the SelectedOptions.Validate method, which makes live API calls using the submitted credentials to verify they are correct before saving them. This prevents a user from entering an invalid state.
For more details on this feature, see the Runtime Settings documentation.
API selection
The application can fetch content from two different Contentful APIs: the Content Delivery API (CDA) and the Content Preview API (CPA). The choice depends on the UsePreviewApi flag in the active ContentfulOptions.
When to use Delivery API (CDA)
- Environment: Production.
- Content: Accesses published entries only.
- Key:
DeliveryApiKey. - Characteristics: This is the primary API for delivering content to end-users. It is globally distributed via CDN for high performance and availability. Rate limits are high.
- Activation: Set
UsePreviewApitofalse. This is the default setting inappsettings.json.
When to use Preview API (CPA)
- Environment: Development, Staging, or for content editors.
- Content: Accesses both published and draft (unpublished) entries.
- Key:
PreviewApiKey. - Characteristics: This API is designed for previewing content before it goes live. It is not cached by the CDN and has lower rate limits. It should not be used for production traffic.
- Activation: Set
UsePreviewApitotrue.
The application provides a simple toggle in the UI to switch between the two APIs at runtime. This is handled by the OnPostSwitchApi method in the SettingsModel, which updates only the UsePreviewApi flag in the session's ContentfulOptions.
TheExampleApp/Pages/Settings.cshtml.cs
csharp
/// <summary>
/// Post action from the dropdown to switch api.
/// </summary>
/// <param name="api">The api to switch to.</param>
/// <param name="prevPage">The page that originated the post.</param>
/// <returns>A redirect result back to the originating page.</returns>
public IActionResult OnPostSwitchApi(string api, string prevPage)
{
// Retain all options except whether to use the preview api or not.
var options = new ContentfulOptions
{
UsePreviewApi = api == "cpa", // "cpa" for Preview, "cda" for Delivery
DeliveryApiKey = _manager.Options.DeliveryApiKey,
SpaceId = _manager.Options.SpaceId,
PreviewApiKey = _manager.Options.PreviewApiKey,
// ... other properties
};
HttpContext.Session.SetString(nameof(ContentfulOptions), JsonConvert.SerializeObject(options));
return Redirect($"{prevPage}?api={api}");
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
This allows developers and content editors to seamlessly switch to Preview Mode to view draft content directly within the application.