OpenAPI Generator

Generating Angular (and other) REST Clients

about me

  • Esteban Gehring (esteban.gehring@bithost.ch)
  • Github: @macjohnny
  • Full Stack Developer at Bithost GmbH
    • Clients: BKW, Raiffeisen, Mobiliar, Porsche, ...
  • Keen on TypeScript/Angular/Java/Spring Boot
  • Member of the OpenAPI Generator
    TypeScript Technical Committee
  • Contributor to OpenAPI Generator since 2017

API First

define API, before coding, in specification

opensource.zalando.com/restful-api-guidelines/

What?

Write a YAML or JSON File according to the
OpenAPI Specification (swagger.io/specification)

HOW?

  • Definition
  • Documentation
  • Client / Server Interface Generation

WHY?

Openapi Specification

  • YAML File for defining REST APIs

  • Formerly known as Swagger Spec

  • Sections with

    • Paths (REST-Endpoints)

    • Schemas (Models)

    • Reusable Parameters

  • swagger.io/specification

  • Extended Example: petstore.yaml

OpenAPI Specification Example

openapi: "3.0.0"
paths:
  /pets/{petId}:
    get:
      parameters:
        - name: petId
          in: path
          schema:
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'
components:
  schemas:
    Pet:
      properties:
        id:
          type: integer

api-definition.yaml

Openapi Generator

  • Generate Models and REST API Classes from OpenAPI Spec File
    • Generate Backend Service Interfaces (Java, C#, Go, ...)
    • Generate Frontend Clients (Angular, JavaScript, ...)
    • Generate Docs/Schemas (HTML, GraphQL, MySQL, ...)
  • github.com/OpenAPITools/openapi-generator
  • Fork of Swagger Codegen
  • Used at SIX, Siemens, SUVA, Raiffeisen, Yelp, Zalando, ...
  • Supports OpenAPI/Swagger Spec 2.0 and 3.0

Openapi Generator - Approaches

  • Define API in OpenAPI Spec File
  • Generate Frontend Clients / Backend
  • Generate OpenAPI Spec File
    from annotated REST Controllers
  • Generate Frontend Clients / Backend 

API First

Annotate Existing API

Openapi Generator

How to use it

npm install @openapitools/openapi-generator-cli -g

openapi-generator help

Openapi Generator

gENERATE bACKEND SERVER INTERFACES

openapi-generator generate -i api-definition.yml \
	-g spring -o backend-interfaces
public interface PetsApi {
    ...
    @RequestMapping(value = "/pets/{petId}", 
        method = RequestMethod.GET)
    default ResponseEntity<Pet> showPetById(
        @PathVariable("petId") Integer petId
    ) {
        return new ResponseEntity<>(...);
    }

Output: PetsApi.java

Openapi Generator

gENERATE bACKEND SERVER INTERFACES

@RestController
public class PetsApiController implements PetsApi {
    ...
    @Override
    ResponseEntity<Pet> showPetById(
        @PathVariable("petId") Integer petId
    ) {
        return new ResponseEntity<>(...);
    }
}

Implement it:

Openapi Generator

gENERATE Frontend angular client

openapi-generator generate -i api-definition.yml \
	-g typescript-angular -o frontend-client \
	--additional-properties=npmName=demo-api
@Injectable()
export class PetsService {
    public showPetById(petId: number): Observable<Pet> {
        ...
        return this.httpClient.get<Pet>(
            `{...}/pets/${encodeURIComponent(String(petId))}`
        );
    }

Output: PetsService.ts

Openapi Generator

gENERATE Frontend angular client

{
  "name": "demo-api",
  "scripts": {
    "build": "ng-packagr -p ng-package.json"
  },
  ...
}

Output: package.json

We also get a package.json in order to publish the
API Client as an NPM package, if wanted:

frontend angular client

usage

import { Pet, PetsService } from './api';

@Component({...})
export class AppComponent {
  favoritePet: Pet;

  constructor(private petsService: PetsService) {}

  loadFavoritePet() {
    this.petsService.showPetById(6)
    .subscribe(pet => this.favoritePet = pet);
  }
}

Usage in AppComponent.ts

frontend angular client

type safety

paths:
  /pets:
    get:
      parameters:
        - name: livingEnvironment
          in: query
          schema:
            $ref: '#/components/schemas/LivingEnvironment'
components:
  schemas:
    LivingEnvironment:
      type: string
      enum:
        - Water
        - Land
        - Air

api-definition.yml

frontend angular client

type safety

export type LivingEnvironment = 'Water' | 'Land' | 'Air';

export const LivingEnvironment = {
    Water: 'Water' as LivingEnvironment,
    Land: 'Land' as LivingEnvironment,
    Air: 'Air' as LivingEnvironment
};

export class PetsService {
    public listPets(
    	searchKeyword?: string, 
    	livingEnvironment?: LivingEnvironment
    ): Observable<Array<Pet>>; {
      ...
    }
}

Output: PetsService.ts

frontend angular client

type safety

import { LivingEnvironment, Pet, PetsService } from './api';

@Component({...})
export class AppComponent {
  searchKeyword: string;
  livingEnvironment: LivingEnvironment = 'Water';
  pets: Pet[];

  constructor(private petsService: PetsService) {}

  loadPets() {
    this.petsService.listPets(
      this.searchKeyword,
      this.livingEnvironment
    ).subscribe(pets => this.pets = pets);
  }

Usage in AppComponent.ts

frontend angular client

type safety - create model

export interface Pet { 
    id: number;
    name: string;
    tag?: string;
    livingEnvironment?: LivingEnvironment;
}

Generated Model: pet.ts

export class AppComponent {
  createPet() {
    this.petsService.createPet({
    	id: 445, 
        name: 'Bob', 
        livingEnvironment: LivingEnvironment.Water
    }).subscribe();

Create Model in AppComponent.ts

frontend angular client

Publish library

openapi-generator generate -i api-definition.yml \
  -g typescript-angular -o frontend-client \
  --additional-properties=npmName=demo-api,npmVersion=1.2.3

cd frontend-client/
npm install
npm run build
npm publish dist

Publisher

npm install demo-api@1.2.3

Consumer

frontend angular client

read more

openapi generator

community

 

sponsors

openapi generator

REVIEW

«We use OpenAPI for several applications and appreciate the easy and efficient way of defining and documenting an API.
The code generation with OpenAPI Generator for both, Angular Frontends und Spring Boot Backends ensures that service consumer and provider speak the same language.»

 

Sven Huber, Senior Software Developer, Raiffeisen Schweiz

useful tools

thanks for your attention!

OpenAPI Generator

Generating Angular (and other) REST Clients

Made with Slides.com