define API, before coding, in specification
Write a YAML or JSON File according to the
OpenAPI Specification (swagger.io/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: "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
npm install @openapitools/openapi-generator-cli -g
openapi-generator help
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
@RestController
public class PetsApiController implements PetsApi {
...
@Override
ResponseEntity<Pet> showPetById(
@PathVariable("petId") Integer petId
) {
return new ResponseEntity<>(...);
}
}
Implement it:
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
{
"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:
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
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
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
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
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
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
«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