Show Swagger Document in an Angular App

Recently I had an interesting request from one of my customers. They wanted to have an API documentation close to its frontend, developed in Angular. Well, actually a web designer would create a webpage and from an API the page would load the data to put it on the page. But why we will go this way? We have mostly a Swagger document, in YAML or JSON, and probably a Swagger account to give acces to our customers. If we don't have an account, we still have the Swagger document. This document is essential bounded to our development, so it would be great to use it.

So, as the customer said “please add the documentation into my frontend application”, a challenge started. Here I will describe the solution and the traps I have fallen into.

My journey begun with a search for a npm package which deals Swagger documents well. I found some but swagger-ui from npm was the one and only package which looked the best.

> npm install --save swagger-ui

To use it in a page first we need an angular component for it. I started the Angular server:

> ng serve

Then I moved into the folder where the part of the webpage is stored in which I wanted to add the Swagger documentation. In my case, it was the settings dialog. Here I created a new component called api-documentations: 

> ng generate component api-documentations

That created a subfolder with four files:

A list of generated files 

 

  1. api-documentations.component.html is the design part of my new component but will not get any special stuff.
  2. api-documentations.component.scss is the file with stylesheet definitions, but will not be used here.
  3. api-documentations.component.spec.ts could be used for tests but I dont have any
  4. api-documentations.component.ts this is will come the main part of my implementation

Let's take a look into the .html file. Here I changed only one thing but after a few errors I found out what was the important.

<div #customersapidocumentation id="customer-api-documentation"></div>

It's important to have a div which contains an id in type of #[name the id you like]. If you google for a Swagger implementation you will find some “solutions” but the way with # will work due to the ViewChild-Selector in Angular.

This id we need to assign the Swagger generated content. This will happen in the .ts file. So lets move to the api-documentations.component.ts file.

First, I imported the swagger-ui package and the Swagger documentation as json:

import SwaggerUI from 'swagger-ui';
import customerApiDoc from './customerAPI-1.0.json'

in the compiler options.

Back to my component. After the @Component section I implemented the AfterContentInit interface and put the assignment code into the ngAfterContentInit() method. Finally the connection between html and generated documentation needs to be setup by define a ViewChild element.

In the end the code in the .ts file looks like this:

import { ElementRef } from '@angular/core';
import { Component, ViewChild, AfterContentInit } from '@angular/core';
import SwaggerUI from 'swagger-ui';
import customerApiDoc from './customerAPI-1.0.json';
@Component({ ... })export class ApiDocumentationsComponent implements AfterContentInit {
@ViewChild('customerapidocumentation',{static: true}) custApiDocElement: ElementRef | undefined
constructor() { } ngAfterContentInit(): void {
const apiDocumentation = customerApiDoc;
const ui = SwaggerUI({
spec: apiDocumentation,
domNode: this.custApiDocElement?.nativeElement,
})
}
}
 

You can load the Swagger file from a public http endpoint too. Just enter the url and it will work. In some documentations for swagger-ui you will see that you have to take dom_id. Don't do it, it's wrong and will not work.

To find out what the right solution, it was an interesting way. But the result is awesome. It looks like a original Swagger documentation. If you change the document, you will channge the generated result too. For example I’ve removed the virtual server part from my json file and the result is there is no server anymore. Obviously.

PS: maybe you will ask why the documentation will not show in your implementation. Let me guess one, you did not add the selector in your page somewhere?