Create an Angular Client using OpenAPI Specifications

Guide to Generating Typescript Code from OpenAPI Specification Files and Using It in Angular Projects

Patric
9 min readApr 27, 2023

--

Using OpenAPI Generator with TypeScript-Angular in Angular Projects: A Hands-On Guide

OpenAPI Generator is a powerful tool that generates client-side code from an OpenAPI specification file. This code can be used to communicate with an API server and includes models, request and response objects, and API clients.

TypeScript-Angular is a popular framework for building web applications using the Angular platform, which is built on TypeScript. It provides many features to help developers build scalable and maintainable applications, including dependency injection, component-based architecture, and powerful data binding.

In this article, we will explore using OpenAPI Generator with TypeScript-Angular to quickly and easily generate code to communicate with an API server. We’ll provide a step-by-step guide on how to set up OpenAPI Generator and typescript-angular in an Angular project, how to use the generated code in Angular components and services, and how to customize the generated code to meet specific project requirements. Additionally, we’ll provide some best practices and tips for using these tools in Angular projects. By the end of this article, you’ll understand how to use OpenAPI Generator and TypeScript-Angular to make building Angular applications with API integration much easier and more efficient.

Setup Project and Dependencies

Step 1: Install Required Dependencies

Before you can use OpenAPI Generator and typescript-angular in your Angular project, you’ll need to install a few dependencies. First, make sure you have Node.js and npm installed on your system. You can check if you have them installed by running the following commands in your terminal:

node -v
npm -v

If you don’t have Node.js and npm installed, you can download them from the official website: https://nodejs.org/en/download/

Install the OpenAPI Generator package globally. You can do this by running the following command in your project’s root directory:

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

Step 2: Generate Code from OpenAPI Specification

Once you have installed the required dependencies, you can generate code from your OpenAPI specification file. To do this, you’ll need to download your OpenAPI specification file in either JSON or YAML format.

Here is an example YAML specification file that you can use:

# openapi.yaml
openapi: 3.0.0
info:
title: My API
version: 1.0.0
paths:
/login:
post:
summary: Login with email and password
operationId: login
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
type: string
format: email
password:
type: string
format: password
required:
- email
- password
responses:
'200':
description: Login successful
content:
application/json:
schema:
type: object
properties:
token:
type: string
format: JWT
user:
$ref: '#/components/schemas/User'
'401':
description: Invalid email or password
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/users:
get:
summary: Get all users
description: Returns a list of all users in the system
operationId: getUsers
security:
- JWT: []
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
'401':
$ref: '#/components/responses/UnauthorizedError'
/users/{userId}:
get:
summary: Get a user by ID
description: Returns a single user by ID
operationId: getUserById
parameters:
- name: userId
in: path
required: true
description: ID of the user to retrieve
schema:
type: string
security:
- JWT: []
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
'401':
$ref: '#/components/responses/UnauthorizedError'
/users/{userId}/posts:
get:
summary: Get all posts for a user
description: Returns a list of all posts for a given user
operationId: getPostsByUserId
parameters:
- name: userId
in: path
required: true
description: ID of the user to retrieve posts for
schema:
type: string
security:
- JWT: []
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Post'
'401':
$ref: '#/components/responses/UnauthorizedError'
/posts:
get:
summary: Get all posts
description: Returns a list of all posts in the system
operationId: getPosts
security:
- JWT: []
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Post'
'401':
$ref: '#/components/responses/UnauthorizedError'
components:
securitySchemes:
JWT:
type: http
scheme: bearer
bearerFormat: JWT
responses:
UnauthorizedError:
description: The user is not authorized to access this resource.
headers:
WWW-Authenticate:
description: The authentication challenge header.
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
Error:
type: object
properties:
code:
type: integer
message:
type: string
required:
- code
- message
User:
description: A simple user model.
type: object
properties:
id:
type: string
name:
type: string
email:
type: string
required:
- id
- name
- email
Post:
type: object
properties:
id:
type: string
userId:
type: string
title:
type: string
body:
type: string
required:
- id
- userId
- title
- body

Once you have your specification file, you can generate client-side code using the OpenAPI Generator CLI. Please place your openapi.yaml beside the angular project folder.

Generate a new Angular project:

ng new client

Generate code & integrate generated code

To generate TypeScript code for Angular, you can run the following command:

npx openapi-generator-cli generate -i openapi.yaml -g typescript-angular -o client/src/app/core/modules/openapi --additional-properties fileNaming=kebab-case,withInterfaces=true --generate-alias-as-model

In this example, we’re using the typescript-angular generator to generate Angular code from the openapi.yaml file. The generated code will be placed in the client/src/app/core/modules/openapi directory.

Now we need to import the generated module in our app.module.ts:

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'

import { AppRoutingModule } from './app-routing.module'
import { AppComponent } from './app.component'
import { ApiModule } from './core/modules/openapi'

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, ApiModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}

To configure the OpenAPI-generated ApiModule to use a different host, you can use the BASE_PATH injection token provided by the generated code. Here's an example of how you can configure the module to use a different local host:

// ...

@NgModule({
// ...
providers: [{ provide: BASE_PATH, useValue: 'http://localhost:3000' }]
})
export class AppModule { }

In this example, we import the ApiModule from the OpenAPI-generated code and define a new module CustomApiModule that imports the ApiModule. We also provide a new value for the BASE_PATH injection token using the provide and useValue syntax.

In this case, we’re setting the BASE_PATH to http://localhost:3000, which is a different local host than the default value used by the generated code. You can replace this value with any valid URL for your API host.

By providing a new value for BASE_PATH, the generated API client will make requests to the new host specified in useValue instead of the default host specified in the OpenAPI specification file.

Here’s an example of how to use the generated service to make a call to your API:

// src/app/services/user.service.ts

import { Injectable } from '@angular/core'
import { Observable } from 'rxjs'
import { DefaultService, User } from '../core/modules/openapi'

@Injectable({
providedIn: 'root',
})
export class UserService {
constructor(private api: DefaultService) {}

getUsers(): Observable<User[]> {
return this.api.getUsers()
}
}

You have now installed and set up OpenAPI Generator and typescript-angular in your Angular project, generated code from your OpenAPI specification file, and configured the generated code to work with your Angular project.

Now we are going to write a Component that makes use of the UserService:

// components/user-list/user-list.component.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from '../path/to/user.service';
import { User } from '../core/modules/openapi';

@Component({
selector: 'app-user-list',
template: `
<h1>User List</h1>
<ul>
<li *ngFor="let user of users$ | async">{{ user.name }}</li>
</ul>
`
})
export class UserListComponent implements OnInit {
users$: Observable<User[]>;

constructor(private userService: UserService) {}

ngOnInit() {
this.users$ = this.userService.getUsers();
}
}

In this component, we define a users$ property that holds an observable list of users. We inject the UserService into the constructor and use it in the ngOnInit method to retrieve the list of users.

The HTML template displays the list of users using a ngFor loop that iterates over the users$ observable and indicates the name of each user.

Note that you will need to replace path/to/user.service with the path to your UserService file, and ../core/modules/openapi with the path to your OpenAPI-generated API client.

Customizing Generated Code in OpenAPI Generator for Angular Projects

While OpenAPI Generator provides a convenient way to generate code based on an OpenAPI specification, you may find that the generated code doesn’t exactly meet your project’s specific requirements. Fortunately, you can customize the generated code to add custom logic, validation, or other features as needed. Here are some ways to do that:

  1. Extend the generated classes: The generated code includes services, models, and API clients that you can extend to add custom behavior. For example, you can extend a generated service to add additional methods or modify the behavior of existing methods. Similarly, you can extend a generated model to add custom validation or formatting logic.
  2. Use codegen options: OpenAPI Generator provides a variety of codegen options that allow you to customize the generated code. For example, you can use the additional-properties option to add additional properties to the generated models, or the model-name-prefix option to add a prefix to the generated model names. Here you can see the full list of options.

When customizing the generated code, it’s important to keep in mind that any changes you make may be overwritten if you regenerate the code from the OpenAPI specification file. To avoid losing your changes, you should consider using version control and branching strategies to manage changes to the generated code.

Extend the generated classes

Here’s an example of how to extend and overwrite a generated model:

We use the generated User model from above. If we want to add a new property to the User model, we can extend the generated model and add the new property. Here's an example of how we can do that:

// src/app/model/user.ts
import { User as GeneratedUser } from '../core/modules/openapi/model/user'

export interface User extends GeneratedUser {
age: number
}

In this example, we import the generated User model and extend it using the extends keyword. We also add a new age property to the model.

Best Practices and Tips for Using OpenAPI Generator and typescript-angular in Angular Projects

Here are some best practices and tips for using OpenAPI Generator and typescript-angular in Angular projects:

  1. Code Organization: Organize your generated code in a separate directory or module to keep it isolated from your application code. This will make it easier to manage and update your generated code as your API evolves over time.
  2. Naming Conventions: Use consistent naming conventions for your generated code, such as prefixing generated services with “Api” or “Service” to differentiate them from application services. This will help keep your code organized and easy to understand.
  3. Error Handling: Handle API errors in a consistent way across your application. You can use Angular’s HttpErrorResponse class to handle HTTP errors returned by the API, and create custom error classes to represent API-specific errors.
  4. Testing: Write unit tests for your generated services and API clients to ensure that they are working correctly. You can use the HttpClientTestingModule module to mock HTTP requests and responses, and the HttpTestingController class to verify that the correct requests are being sent to the API.
  5. Customization: Use partial classes to add custom logic or properties to the generated code, rather than modifying the generated code directly. This will make it easier to manage changes and updates to the generated code over time.
  6. Code Generation Options: Use code generation options to customize the generated code to meet your specific project requirements. For example, you can use the useOptionsProvider option to generate services with an options parameter, which can be used to pass additional options to API requests.
  7. Security: Ensure that your API requests are secure by using HTTPS and properly handling authentication tokens. You can use Angular’s HttpClientInterceptor class to intercept HTTP requests and add authentication headers to API requests.

By following these best practices and tips, you can use OpenAPI Generator and typescript-angular to quickly and efficiently generate code for your Angular project, while ensuring that your code is organized, secure, and easy to maintain.

Conclusion: Using OpenAPI Generator and typescript-angular in Angular Projects

In this article, we covered the basics of OpenAPI Generator and typescript-angular, and how to use them to quickly generate code for Angular projects based on an OpenAPI specification. We covered the steps required to install and set up OpenAPI Generator and typescript-angular, and how to customize the generated code to meet specific project requirements.

We also provided some best practices and tips for using OpenAPI Generator and typescript-angular in Angular projects, including organizing your generated code, using consistent naming conventions, handling errors, testing your code, and customizing the generated code with partial classes.

Overall, the benefits of using OpenAPI Generator and typescript-angular in Angular projects include the ability to quickly generate code based on an OpenAPI specification, which can save time and reduce the risk of errors. However, there are also some challenges to using these tools, such as the need to carefully manage the generated code and ensure that it is properly integrated with your application code.

Despite these challenges, OpenAPI Generator and typescript-angular can be powerful tools for building Angular applications that interact with RESTful APIs. By following best practices and tips for using these tools, developers can ensure that their code is well-organized, secure, and easy to maintain over time.

--

--

Patric

Loving web development and learning something new. Always curious about new tools and ideas.