revelio

Enterprise Web API Documentation

Extending Revelio

Revelio gives you plenty of functionality out-of-the-box through the intuitive engine and standard attributes, but every API is unique. Therefore, Revelio supports custom information discovery in the form of attributes and processors. To start, you'll want to install the Revelio.Extend NuGet package in your .NET Web API project.

PM> Install-Package Revelio.Extend

Attributes

Revelio has four interfaces that support customizable documentation:

  • IEndpointDocumentationAttribute
  • ITypeDocumentationAttribute
  • IParameterDocumentationAttribute
  • IPropertyDocumentationAttribute
A single attribute can implement one or more of these interfaces.

For example, a site may use an attribute RequirePermission on individual endpoints. This attribute takes one or more permission names, which can be highlighted in Revelio.

public class RequirePermissionAttribute : Attribute, IEndpointDocumentationAttribute
{
    public object RequiredPermissions { get; set; }
    public void AddInfo(ApiEndpointInfo endpoint)
    {
        endpoint.AddMetadata("Required Permissions", RequiredPermissions);
    }
}

Custom information is added via the Metadata dictionary, which is then displayed via a custom view.

Processors

Processors are similar to attributes in that they allow you to modify information or add new metadata to your documentation. However, processors are different in that they are run on every respective object, as opposed to attributes that are only run on the objects they decorate.

For example, say the RequirePermissionAttribute class described earlier was an external class, so we couldn't modify the code to add the IEndpointDocumentationAttribute implementation. Instead, we can write a processor that adds the metadata for any endpoint with that attribute.

public class RequirePermissionsProcessor : IEndpointDocumentationProcessor
{
    public void AddInfo(MethodInfo methodInfo, ApiEndpointInfo endpoint)
    {
        var attribute = methodInfo.GetCustomAttribute<RequirePermissionAttribute>();
        if (attribute == null) return;
        endpoint.AddMetadata("Required Permissions", attribute.RequiredPermissions);
    }
}

The final step is to add this processor to the project's Revelio configuration. This is a class that implements IRevelioConfiguration declared in the Web API project. Revelio will use this class to add custom processors.

public class RevelioConfiguration : IRevelioConfiguration
{
    public IEnumerable<IEndpointDocumentationProcessor> ListApiEndpointProcessors()
    {
        return new List<IEndpointDocumentationProcessor> { new RequirePermissionsProcessor() };
    }
    public IEnumerable<ITypeDocumentationProcessor> ListApiTypeProcessors()
    {
        throw new System.NotImplementedException();
    }
    public IEnumerable<IParameterDocumentationProcessor> ListApiParameterProcessors()
    {
        throw new System.NotImplementedException();
    }
    public IEnumerable<IPropertyDocumentationProcessor> ListApiPropertyProcessors()
    {
        throw new System.NotImplementedException();
    }
}

Now this processor will be run every time the documentation is generated. In order to simplify your development, Revelio will ignore any NotImplementedException thrown from this class.

FindAttributeProcessor

Many times you'll find yourself writing a processor to search for a specific attribute. Revelio provides the helper processor FindAttributeProcessor<T> for such a case. We could rewrite the RequirePermissionsProcessor to the following:

public class AnotherRequirePermissionsProcessor : FindAttributeProcessor<RequirePermissionAttribute>
{
    protected override void ProcessAttributes(ApiEndpointInfo endpoint, IEnumerable<RequirePermissionAttribute> attributes)
    {
        endpoint.AddMetadata("Required Permissions", attributes.First().RequiredPermissions);
    }
}