Content delivery API in Umbraco 12 RC 1 - Did I say Headless?

Headless in Umbraco core

Content delivery API in Umbraco 12 RC 1 - Did I say Headless?

Umbraco 12 Release Candidate 1 was released yesterday, 17 May 2023. There were quite a few features in this release as described in the release notes. But what I was most excited about was the Content Delivery API.

As a member of the Umbraco Headless Community Team, I was aware of this and we as a team had made several suggestions on the direction of this feature.

Documentation

The official Content Delivery API documentation is pretty comprehensive and is a good place to start.

Installing 12RC1 on your local machine

If you want to try it out on your local machine, the Package Script Writer by Paul Seal is an excellent resource. Within a few minutes, you will have Umbraco 12 RC 1 installed and ready to test out on your local machine.

Installing 12RC1 on an Azure Web App

But of course, I wanted to try this out on Azure and share it with the devs at Luminary. I've got this nifty script that I run on an Azure Cloud Shell. In around 20 minutes I get a fully functional Umbraco 12 RC 1 with the Content Delivery API enabled.

wget https://www.speedycmsinstall.com/scripts/azure/v12rc1/create-umbraco-v12rc1-demo.sh
chmod +x create-umbraco-v12rc1-demo.sh
./create-umbraco-v12rc1-demo.sh

You can fork the bash script from GitHub and tinker with it for your own needs. If you need more details on this script, you can read all about it in Scripting an Azure deployment of Umbraco 9.

Starter Kit installed

My bash script also installed the "Starter Kit" which gave me some content to play with while testing out the new Content Delivery API.

Trying out the Content Delivery API

I tried the most obvious choices for testing out the content delivery API. Note that the following URLs may not work in the future as this test environment is ephemeral.

Retrieving all the content

Retrieving all the content was easy enough.

curl --location "https://umbracov12rc1-demo-19175.azurewebsites.net/umbraco/delivery/api/v1/content"

But it seemed I was missing something. I know that my name was included in this Starter Kit. But the Delivery API did not return that item to me.

{
    "total": 30,
    "items": [
        {
            "name": "Home",
            "route": {
                "path": "/",
                "startItem": {
                    "id": "ca4249ed-2b23-4337-b522-63cabe5587d1",
                    "path": "home"
                }
            },
            "id": "ca4249ed-2b23-4337-b522-63cabe5587d1",
            "contentType": "home",
            "properties": {
                "heroHeader": "Umbraco Demo",
                // removed for brevity
            },
            "cultures": {}
        },
        {
            "name": "Products",
            // removed for brevity
        },
        // removed for brevity
        {
            // item #10
            "name": "Biker Jacket",
            // removed for brevity
        }
    ]
}

Since it said that there were 30 items in total, I tried the take query parameter as follows:

curl --location "https://umbracov12rc1-demo-19175.azurewebsites.net/umbraco/delivery/api/v1/content?take=30"

Voila! I can now see 30 items and myself in the JSON results.

{
    "total": 30,
    "items": [
        {
            "name": "Home",
            // removed for brevity
        },
        // removed for brevity
        {
            "name": "People",
            // removed for brevity
        },
        // removed for brevity
        {
            "name": "Emmanuel Tissera",
            "route": {
                "path": "/people/emmanuel-tissera/",
                // removed for brevity
            },
            "id": "6374bda9-034a-4109-a837-72ed6a325f11",
            "contentType": "person",
            "properties": {
                "seoMetaDescription": "",
                "keywords": [],
                "umbracoNavihide": false,
                "photo": [
                    {
                        "id": "77db56ab-2f79-4eb2-82fd-eb7266e6b366",
                        "name": "Emmanuel Tissera",
                        "mediaType": "Image",
                        "url": "/media/vvlnw31z/emmanuel_tissera.jpg",
                        "extension": "jpg",
                        "width": 1600,
                        "height": 1200,
                        "bytes": 772875,
                        "properties": {},
                        "focalPoint": null,
                        "crops": []
                    }
                ],
                "department": [
                    "Australia",
                    "mvp"
                ],
                "email": "",
                "twitterUsername": "",
                "facebookUsername": "",
                "linkedInUsername": "",
                "instagramUsername": ""
            },
            "cultures": {}
        },
        // removed for brevity
        {
            // Item #30
            "name": "Contact",
            // removed for brevity
        }
    ]
}

⚠️ I believe the Content Delivery API is missing a pagination block to let consumers know how many records have been returned and how they should reach for the next set.

Retrieve a particular item via ID

Request:

curl --location "https://umbracov12rc1-demo-19175.azurewebsites.net/umbraco/delivery/api/v1/content/item/6374bda9-034a-4109-a837-72ed6a325f11"

Response:

{
    "name": "Emmanuel Tissera",
    "route": {
        "path": "/people/emmanuel-tissera/",
        "startItem": {
            "id": "ca4249ed-2b23-4337-b522-63cabe5587d1",
            "path": "home"
        }
    },
    "id": "6374bda9-034a-4109-a837-72ed6a325f11",
    "contentType": "person",
    "properties": {
        "seoMetaDescription": "",
        "keywords": [],
        "umbracoNavihide": false,
        "photo": [
            {
                "id": "77db56ab-2f79-4eb2-82fd-eb7266e6b366",
                "name": "Emmanuel Tissera",
                "mediaType": "Image",
                "url": "/media/vvlnw31z/emmanuel_tissera.jpg",
                "extension": "jpg",
                "width": 1600,
                "height": 1200,
                "bytes": 772875,
                "properties": {},
                "focalPoint": null,
                "crops": []
            }
        ],
        "department": [
            "Australia",
            "mvp"
        ],
        "email": "",
        "twitterUsername": "",
        "facebookUsername": "",
        "linkedInUsername": "",
        "instagramUsername": ""
    },
    "cultures": {}
}

🌟Worked as expected.

Retrieve a particular item via Path

Request:

curl --location "https://umbracov12rc1-demo-19175.azurewebsites.net/umbraco/delivery/api/v1/content/item/people/emmanuel-tissera"

Response:

{
    "name": "Emmanuel Tissera",
    "route": {
        "path": "/people/emmanuel-tissera/",
        "startItem": {
            "id": "ca4249ed-2b23-4337-b522-63cabe5587d1",
            "path": "home"
        }
    },
    // removed for brevity - same as above
}

💪Worked as expected and I just needed to only know the path of the content item I was hoping to retrieve.

Retrieve draft/preview content

There are times when you need to preview draft content and the Content Delivery API does a great job with this.

curl --location "https://umbracov12rc1-demo-19175.azurewebsites.net//umbraco/delivery/api/v1/content/item/6374bda9-034a-4109-a837-72ed6a325f11" --header "Preview: true" --header "Api-Key: my-secret"

Response:

{
    "name": "Emm Tissera",
    "route": {
        "path": "/people/emmanuel-tissera/",
        "startItem": {
            "id": "ca4249ed-2b23-4337-b522-63cabe5587d1",
            "path": "home"
        }
    },
    // removed for brevity
    "properties": {
        // removed for brevity
        "email": "",
        "twitterUsername": "dAmazingNut",
        "facebookUsername": "",
        "linkedInUsername": "",
        "instagramUsername": ""
    },
    "cultures": {}
}

👀As you can see there is preview content where I have changed the name of the content item and added a twitterUsername. These changes are not visible on the public API.

Adding a new Document Type

To just test how easy this was, I added a new Document Type called Pet. I populated the details of my two dogs and made this request.

curl --location "https://umbracov12rc1-demo-19175.azurewebsites.net//umbraco/delivery/api/v1/content/?filter=contentType:pet"

Without writing a single line of code in the CMS back office, I get this JSON response.

{
    "total": 2,
    "items": [
        {
            "name": "Shadow",
            "route": {
                "path": "/people/shadow/",
                "startItem": {
                    "id": "ca4249ed-2b23-4337-b522-63cabe5587d1",
                    "path": "home"
                }
            },
            "id": "2b9116f6-a45f-404d-8ef2-64900148eca9",
            "contentType": "pet",
            "properties": {
                "petName": "Shadow",
                "breed": "Staffie",
                "isCuddley": true,
                "dateOfBirth": "2016-10-11T00:00:00Z"
            },
            "cultures": {}
        },
        {
            "name": "Athena",
            "route": {
                "path": "/people/athena/",
                "startItem": {
                    "id": "ca4249ed-2b23-4337-b522-63cabe5587d1",
                    "path": "home"
                }
            },
            "id": "64bf848f-06f3-4856-b730-84d4dbbeab08",
            "contentType": "pet",
            "properties": {
                "petName": "Athena",
                "breed": "Staffie",
                "isCuddley": true,
                "dateOfBirth": "2019-02-11T00:00:00Z"
            },
            "cultures": {}
        }
    ]
}

The Verdict

That was a quick whirlwind tour of the new Umbraco Content Delivery API which is a part of the core offering and I'm loving it. I need to explore the localisation features and see if it passes my GILT or GUILT – Localisation crimes test.

I couldn't see the swagger documentation on Azure and that's something I will explore further.

The team working on the Content Delivery API have done a great job in the first release candidate and I'm hoping they will fix the current limitations they have listed to make this product shine.

Provide your own feedback

If you find issues that are not already reported, please report them on the GitHub tracker by following the link or selecting “🐛 Bug Report” when creating a new issue. That reminds me that I should file a suggestion for that pagination issue I encountered.

Public release

I'm looking forward to the public release of Umbraco 12, which is targeted for June 29, 2023.

The Possibilities

With the Content Delivery API in place, a developer could create new Document types and have Content Authors editing adding and updating content even before the front-end has been built.

This allows for a composable architecture where the content is just another API. With the Content Delivery API in place, Umbraco has placed itself in a strong position in that hybrid headless space.