For a fully headless solution, you will need custom APIs to serve catalogs, categories, and products to your client application.
For any special requirements that are not covered by the out-of-the-box APIs.
The goal is to create endpoints that give you freedom of implementation while respecting our authentication.
Prerequisites
Out-of-the-box Headless API available (for example, by using our Standalone Template as a starting point).
Secrets are set up for your stores, and the URI whitelist is correctly configured in the API Access part of the administration interface. You can learn about it here.
Creating the API Controller
In your project, create a new Class and Inherit from Ucommerce.Web.WebSite.Controllers.HeadlessControllerBase
This will inherit our authentication, restricting its usage to only authenticated clients.
Add a route to your controller. It can match the out-of-the-box route as follows:
[Route("api/v1.0/products")]
In your controller's constructor, you can inject any components you may need in your implementation. For example,
var storeGuid = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)
using System.Globalization;
using System.Security.Authentication;
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;
using Ucommerce.Extensions.Search.Abstractions;
using Ucommerce.Extensions.Search.Abstractions.Models.IndexModels;
using Ucommerce.Extensions.Search.Abstractions.Models.SearchModels;
using Ucommerce.Web.WebSite.Controllers;
namespace project.CustomHeadlessControllers;
[Route("api/v1.0/products")]
public class HeadlessProductController : HeadlessControllerBase
{
private readonly IIndex<ProductSearchModel> _productIndex;
public HeadlessProductController(IIndex<ProductSearchModel> productIndex)
{
_productIndex = productIndex;
}
[HttpGet("")]
public async Task<ActionResult<YourResponseModel>> GetProducts(
[FromQuery] Guid categoryId,
[FromQuery] string cultureCode,
CancellationToken token)
{
var storeGuid =
Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? throw new AuthenticationException());
var culture = new CultureInfo(cultureCode);
var products = _productIndex.AsSearchable(culture).Where(x => x.CategoryIds.Contains(categoryId));
//
var productsResponse = new YourResponseModel()
{
Products = YourMapProducts(products)
};
return productsResponse;
}
// YourMapProducts implementation
}