U13 LTS: Swagger for UmbracoApiController / Controller and UmbracoAuthorizedApiController

Hi, I’m using u13.6 LTS. I want to document my api controllers and umbracoApiControllers. I see that swagger works but I don’t see any docs into the Default API page. How to? Thanks.

Hi @biapar

There are some swagger docs for Umbraco 13 here if that helps:

The section at the bottom shows you how to use your own custom APIs in swagger.

Justin

1 Like

First, I really suggest you upgrade to Umbraco 13.13.1. It has no breaking changes, but a lot of security patches. There is in my opnion absolutely no reason to stay at 13.6.

Having said that, for the Umbraco API controller, we usually do this:

On the controller class, add the following attributes:

[Route("api/v{version:apiVersion}/API_ROUTE_HERE")]
[ApiVersion("1.0")]
[MapToApi("API_NAME_HERE")]
[ApiController]

Annotate your controller methods/endpoints as good as possible, for example

[HttpGet]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(typeof(RESPONSE_TYPE_HERE), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[Route("getbyid")]

Don’t add response types to standard responses, like 404. This will clash with Umbraco and your swagger backend won’t load.

Create a documentation filter in a seperate class ike this:

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace SomeProject.Api.Swagger;

/// <summary>
/// Filter for swagger documentation 
/// </summary>
internal class DocumentationFilter : SwaggerDocumentationFilterCore<TYPE_OF_YOUR_CONTROLLER>
{
	/// <inheritdoc />
	protected override void ApplyOperation(OpenApiOperation operation, OperationFilterContext context)
	{
		operation.Parameters ??= new List<OpenApiParameter>();
	}

	/// <inheritdoc />
	protected override void ApplyParameter(OpenApiParameter parameter, ParameterFilterContext context)
	{
		switch (parameter.Name)
		{
			case "id":
				parameter.Description = "The id (guid) of the node to get";
				parameter.Required = true;
				break;
			default:
				return;
		}
	}
}

This is just a simple example, but you can work from here.

Then you need Swagger gen options that you register your documentation filter to like this:

using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace SomeProject.Api.Swagger;

/// <summary>
/// Options for settings up Swagger 
/// </summary>
internal class GenOptions: IConfigureOptions<SwaggerGenOptions>
{
	/// <summary>
	/// Configures the options for Swagger
	/// </summary>
	/// <param name="options"><inheritdoc cref="SwaggerGenOptions"/></param>
	public void Configure(SwaggerGenOptions options)
	{
		options.SwaggerDoc(
			"API_NAME_SHOULD_MATCH_MAP_TO_API_ON_CONTROLLER",
			new OpenApiInfo
			{
				Title = "API_NAME",
				Version = "API_VERSION"
			});

		options.OperationFilter<DocumentationFilter>();
		options.ParameterFilter<DocumentationFilter>();
	}
}

As you can imagine, it would be wise to add some properties, like the API name or maybe the version in constants to use here and on your controller.

And lastly register it in a composer:

builder.Services.ConfigureOptions<GenOptions>();

Hope this gives you a head start. To be honest, I’m not sure if umbraco authorized controllers are even in Swagger. I know that the replacement for that in Umbraco 14+ is the Management API and there it’s extremely easy to get it into Swagger.

Hi , I had read and followed the instructions in the document, but on the Swagger page, only my new group appears without APIs. Thx.

Hi, thanks for your response. If I annotate with route, I’ll break the the normal umbraco api controller route.

Hi @biapar

Could you share your controller and how you’re registering it? In the meantime, worth double-checking that [MapToApi] matches exactly what’s in your SwaggerDoc() call, and that you’re calling builder.Services.ConfigureOptions<YourGenOptions>().

Justin