Content Delivery without services: Running a Tridion web application without a content delivery stack

Your Tridion Sites powered website get its pages and content from the content delivery micro services *. Those HTTP-based OData services can be simulated to run your development or testing website without the content delivery stack. Or to be more precise, with a simulated content delivery stack. Hoverfly is an API simulation tool which can simulate the content delivery services, removing the need for a real Content Delivery and Content Manager server. I use this when up 20.000 ft high in a plane, to run a website in my IDE without the need for a Content Delivery stack, to save the state of published content, and for testing.
 
The principle is really simple but effective: Hoverfly acts like a proxy between the web application and the content delivery services. Depending on your need Hoverfly can either capture all requests and responses or simulate them. In capture mode Hoverfly will pass all requests from the web app through to the content delivery services and record both request and response. In simulate mode Hoverfly will simulate the responses from an earlier recording.

 
Hoverfly has a browser admin GUI interface where you can set the mode, and see how many requests are captured and simulated. 
 
 
This article focuses on how to get Hoverfly running with a .NET web application, something similar applies for a JAVA web app. The findings below are with the DXA .NET sample website.
 
Hoverfly commands
To be able to run Hoverfly: get and install it, then start it from the command line. Start in capture mode since you do not have any recordings yet.
 
hoverctl start
hoverctl mode capture
 
When you have recorded all the calls you need simply save the recorded calls for later, and switch to simulation mode. In simulation mode you are not calling the real content delivery micro services anymore, all calls are served from the Hoverfly recordings.
 
hoverctl export simulation.json
hoverctl mode simulate
 
In a later session you can start Hoverfly in simulation mode and import the earlier recording.
 
hoverctl start
hoverctl mode simulate
hoverctl import simulation.json
 
Of course there is more to Hoverfly: for example you can set an upstream wired to Fiddler to inspect the calls. And there is a GUI on http://localhost:8888 where you can see some counts how many calls have been recorded and simulated.
 
Proxy settings
For the web app to work with Hoverfly we need to configure a proxy in the Web.config. All traffic from the web app will be routed though Hoverfly's proxy, while all other traffic like from your browser will not use the proxy.

   <system.net>
    <defaultProxy>
      <proxy
        usesystemdefault="true"
        proxyaddress="http://localhost:8500"
        bypassonlocal="false"
      />
    </defaultProxy>
 
 
The discovery-service URL still points to the Content Delivery service you want to record.

Disable ADF for now
There are a few other things to change in the web application. I noticed that on every page request my web app makes some unique calls to the content service. Recording those calls makes no sense since they are unique for every page request, and even worse, in simulation mode those requests fail since they were never recorded. Those unique calls origin from the Ambient Data Framework. While I like ADF and you will see it in any site which uses Experience Manager or Experience Optimization anyway, it needs to be disabled while working with Hoverfly.

In the Web.config comment the AmbientFrameworkModule.
 
<!--<add name="AmbientFrameworkModule" type="Tridion.ContentDelivery.AmbientData.HttpModule" preCondition="managedHandler" />-->

Fixate context
My sandbox uses the DXA example site which has some server side responsiveness going on. For that it uses device detection from the Context Service. For me this makes it harder to record all calls to the content delivery services, since based on the size of the browser windows etc, different calls will be made. I am using a custom StaticContextClaimsProvider with a default set of context claims, no more calls to the Context service.
 
using System.Collections.Generic;
using Sdl.Web.Common.Configuration;
using Sdl.Web.Common.Interfaces;
 
namespace Dxa.Test.Context
{
    /// <summary>
    /// DXA Context Claims Provider using using a hardcoded set of claims for testing.
    /// </summary>
    public class StaticContextClaimsProvider : IContextClaimsProvider
    {
        public IDictionary<string, object> GetContextClaims(string aspectName, Localization localization)
        {
            IDictionary<string, object> claims = new Dictionary<string, object>();
 
            // These claims are part of the claims which the ContextServiceClaimsProvider would return for a laptop with 1600x900 screen
            claims.Add("ui.largeBrowser", false);
            claims.Add("browser.displayHeight", 529);
            claims.Add("browser.displayWidth", 1280);
            claims.Add("device.displayHeight", 720);
            claims.Add("device.mobile", false);
            claims.Add("device.robot", false);
            claims.Add("device.tablet", false);
            claims.Add("device.pixeldensity", 217);
            claims.Add("device.displayWidth", 1280);
            claims.Add("device.pixelRatio", 1.25);
 
            return claims;
        }
 
        public string GetDeviceFamily()
        {
            return null;
        }
    }
}
 
 
Browser Link
Browser Link in Visual Studio is another source of requests we don't need to record. Disable Browser Link from the toolbar in VS, or add this app setting  to the Web.config.
 
  <appSettings>
    <!-- Disable browserlink, it causes unnecessary calls to the content service -->
    <add key="vs:EnableBrowserLink" value="false" />
  </appSettings>
 
 
First requests from the web application after start-up
If you are trying a Hoverfly simulation and your web app does not want to start: check if the calls to the content services on web application start-up are recorded. I found that on the first web app request after start-up the Tridion Sites CIL libraries do two calls which are not repeated on subsequent requests.
 
/discovery.svc/ContentServiceCapabilities
/client/v4/content.svc/$metadata
 
If you start the Hoverfly capture after the web app has started, those calls will not be recorded.
 
PowerShell
I wrapped the most common Hoverfly commands in a few PowerShell scripts. This includes a few scripts to start capturing and simulation. And a script which crawls my sandbox website to make sure all the resources I need are recorded in Hoverfly.
 
 
* The microservices architecture is available in SDL Web 8 and up.