Running the Sitecore Layout Service on ASP.NET Core

This project is based on a fork of the official Sitecore XM-Cloud-Introduction repository. The primary aim is to experiment with moving logic from Custom Content Resolvers, which traditionally require .NET Framework, into an ASP.NET Core environment. The changes have been committed to a separate branch, highlighting this work as a conceptual example rather than a production-ready implementation.

The pull request

I submitted a pull request demonstrating the changes needed to implement this solution in the Sitecore XM-Cloud-Introduction repository. I’ve chosen to keep the PR within my own fork, as I believe it’s more of an example rather than something that should be included in the default repository. You can review the full pull request here: Running the Sitecore Layout Service on ASP.NET Core.

Overview of changes

Before this update, all websites within the XM-Cloud-Introduction solution relied on the default GraphQL endpoint: https://xmcloudcm.localhost/sitecore/api/graph/edge. This has been updated to point to the new ASP.NET Core Layout Service at https://localhost:44380/sitecore/api/graph/edge.

The core of this update lies in the GraphController. This controller now intercepts all GraphQL API requests, forwards them to the original endpoint, and provides the capability to modify the incoming and outgoing data. By using the Sitecore ASP.NET Core SDK, we can serialize and manipulate the content, gaining strong-typed access to placeholders and fields.

For example, a WeatherService can now inject real-time weather data into existing fields or even create new fields dynamically. Additionally, the project introduces a caching layer that stores the results of expensive GraphQL queries, improving performance by reducing redundant API calls.

Exploring a different approach

In considering the architectural approach, it's important to clarify that this solution introduces a new layer within the application stack, which contrasts with the traditional concept of composability where individual services operate independently. This update demonstrates that changes typically handled in Sitecore's JavaScript Rendering SDK (JSS) for Next.js can also be managed within an ASP.NET Core environment. However, it's essential to acknowledge that while this method works effectively, it diverges from the Sitecore ASP.NET Core SDK's intended use. The approach provides an alternative to both JavaScript-based modifications and Custom Content Resolvers that require .NET Framework, especially in scenarios where specific customizations are needed.

This approach can be particularly useful when the goal is to remove custom code from Sitecore itself, accelerating development by avoiding full deployments and site restarts. However, it's important to carefully consider the long-term implications, as introducing such a layer could lead to increased complexity and maintenance overhead.

Short demo video

To give you a better idea of how this works in practice, check out the short demo video below: https://youtu.be/f48flEDC_iA


Additional contributions

In addition to this project, I also contributed to the Sitecore ASP.NET Core SDK by adding a GetRawValue() method in the JsonSerializedField class. This method directly returns the raw JSON string, simplifying scenarios where JSON needs to be deserialized, modified, and re-serialized. Previously, this required using a custom JsonConverter with reflection. This enhancement streamlines the process, making the code cleaner and more maintainable. You can view this contribution here: PR #9 on the Sitecore ASP.NET Core SDK.

I also proposed a change to handle empty string fields in the FieldConverter, as discussed in PR #12. Although this proposal wasn't implemented, it sparked a valuable discussion about the correct approach to deserialization and extensibility. The issue was eventually resolved in a subsequent PR: Custom Content Resolver Support, which modified the FieldParser to support Custom Content Resolvers returning modified JSON.