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
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
-
-
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
- Contributions are very welcome
- Frequent releases (2-4 weeks)
- Chat: Slack
- Get involved: github.com/openAPITools/openapi-generator
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
OpenAPI Generator
By Esteban Gehring
OpenAPI Generator
Generating Angular (and other) REST Clients
- 986