Angular Integration Tutorial
See the Angular Example for a working demo you can run immediately.
Prerequisites
- Node.js ≥ 18, Angular ≥ 17
- ApiSorcery CLI installed (
npm i -g @apisorcery/cli) - Device registered (
apisorcery register) - A
.apisorceryrc.jsonconfigured for your project (Service Config)
Generated File Structure
After running apisorcery generate, the following files are created under outputDir (e.g. src/api/auto/):
auto/
└── {service_code}/
├── Api{Tag}.ts # One file per Swagger tag — do NOT edit
├── model.ts # All request / response types — do NOT edit
├── base.ts # Base helpers — do NOT edit
├── swagger.json # Cached Swagger spec — do NOT edit
└── httpClient/
├── interceptors/
│ ├── request.ts # ✏️ Add auth token here
│ └── response.ts # ✏️ Handle global errors here
├── requests/
│ ├── json.ts # JSON request factory — edit base URL here
│ └── blob.ts # File download factory
└── types/
└── axios.d.tsRe-generation
Files marked do NOT edit are overwritten on every apisorcery generate run. Only modify files inside httpClient/interceptors/ and the baseURL in requests/json.ts.
Angular HttpClient vs Axios
The generated client uses Axios rather than Angular's HttpClient. This keeps the generated code framework-agnostic and avoids the need to inject HttpClient into every service.
Install Dependencies
npm install axiosConfigure Base URL
Open httpClient/requests/json.ts and set your API server address:
const instance = axios.create({
baseURL: 'https://your-api.com', // ✏️ change this
timeout: 10000,
});Configure Auth Token
Open httpClient/interceptors/request.ts:
instance.interceptors.request.use((config) => {
const token = localStorage.getItem('token'); // ✏️ use your own token source
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});Open httpClient/interceptors/response.ts to handle auth errors globally:
instance.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// ✏️ redirect to login via Angular Router
// inject(Router).navigate(['/login']);
}
return Promise.reject(error);
}
);Using the Generated APIs
import { Component, OnInit } from '@angular/core';
import * as ApiUser from '../api/auto/demo/ApiUser';
import type { UserInfoDto } from '../api/auto/demo/model';
@Component({ selector: 'app-user-list', template: '...' })
export class UserListComponent implements OnInit {
users: UserInfoDto[] = [];
async ngOnInit() {
this.users = await ApiUser.getUserList({ page: 1, limit: 10 });
}
}Common Issues
returnLevel — which value should I use?
Most backends wrap responses in { code, data, message }. Use "returnLevel": "second" (the default) to unwrap data automatically. If your API returns the payload directly, use "returnLevel": "first".
Chinese tag names generate uncompilable class names
Add a tagNameMap to your service config:
"tagNameMap": { "用户管理": "User", "订单管理": "Order" }See Service Config for details.