-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
SwaggerToTypeScriptClientGenerator
- Package: NSwag.CodeGeneration.TypeScript
- Settings: SwaggerToTypeScriptClientGeneratorSettings
Inherits from ClientGeneratorBase
The following code generates the TypeScript client code and DTO interfaces from a given Swagger specification:
var document = SwaggerDocument.FromUrl(swaggerSpecUrl);
var settings = new SwaggerToTypeScriptClientGeneratorSettings
{
ClassName = "{controller}Client",
};
var generator = new SwaggerToTypeScriptClientGenerator(document, settings);
var code = generator.GenerateFile();
The used template can be set via the Template
property of the SwaggerToTypeScriptClientGeneratorSettings class.
- Library: jQuery
- Typings: jquery.d.ts
Generates client classes which use JQuery for HTTP handling and simple callbacks for success and error handling.
- Libraries:
- Polyfill:
- Typings:
Generates client classes which use JQuery for HTTP handling and JavaScript Promises to handle asynchronicity. Most modern browsers only support JavaScript ES5 which does not provide a native Promise implementation. You can choose from two promise types via the PromiseType
setting:
- Promise: Generates code which requires native Promises; use a polyfill like ES6 Promise polyfill
- QPromise: Generates code which requires the Q promise library
- Typings: angular.d.ts
Generates an AngularJS service class which uses the AngularJS http service.
The Angular template generates an Angular 2 service to access your backend.
Sample
- Client class name: DataClient
- TypeScript file name: serviceClients.ts
First create an NgModule with the generated services:
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { SampleDataService } from './services';
@NgModule({
imports: [
HttpModule
],
providers: [
SampleDataService
]
})
export class ServicesModule {
}
Usage in an Angular component via dependency injection:
import { Component } from '@angular/core';
import { SampleDataService, WeatherForecast } from '../../services';
@Component({
selector: 'fetchdata',
templateUrl: './fetchdata.component.html'
})
export class FetchDataComponent {
public forecasts: WeatherForecast[];
constructor(sampleDataService: SampleDataService) {
sampleDataService.weatherForecasts().subscribe(result => {
this.forecasts = result;
});
}
}
Extension code which is needed when UseTransformOptionsMethod
or UseTransformResultMethod
is enabled is shown below.
HttpClass: Http
import { Observable } from 'rxjs/Observable'; // ignore
import { Response, RequestOptionsArgs } from '@angular/http'; // ignore
export class MyBaseClass {
protected transformOptions(options: RequestOptionsArgs) {
return Promise.resolve(options);
}
protected transformResult(url: string, response: Response, processor: (response: Response) => any): Observable<any> {
return processor(response);
}
}
HttpClass: HttpClient
export class ServiceBase {
protected transformOptions(options: any) {
return Promise.resolve(options);
}
protected transformResult(url: string, response: HttpResponse<Blob>, processor: (response: HttpResponse<Blob>) => any): Observable<any> {
return processor(response);
}
}
- Polyfills:
- Typings:
Template for the official window.fetch API with promises.
- Dependencies:
- Polyfill:
Template for Aurelia using the HttpClient
from aurelia-fetch-client
. By using the HttpClient via dependency injection you can add global interceptors and other global configurations. When using a global response interceptor, beware that the generated TypeScript code calls the text() method to read the response. Because the response of a fetch call can only be read once, you cannot call arrayBuffer()
, blob()
, json()
, text()
or formData()
on the response object yourself or the generated TypeScript code will throw an exception. If you need to read the response in your interceptor, you should clone the response first and perform the text()
function or equivalent on the cloned Response (like this: response.clone().text()
).
- When generating DTO classes instead of interfaces, datetime values are automatically converted into a
Date
or MomentJSmoment
object.
It is possible to extend the generated classes with own code. With this mechanism, you can add specific security code, caching or additional headers, new methods or properties. This works for client classes as well as the DTO classes. The external code is specified with the "ExtensionCode" setting. It accepts source code or a path to a .ts file (recommended).
Related Settings:
- TypeScriptGeneratorSettings.ExtensionCode: The external code
- TypeScriptGeneratorSettings.ExtendedClasses (requires extension code): The names of the extended classes
- BaseClass (requires extension code): The base class of all generated client classes
Check out the NJsonSchema documentation for more information.
In the ExtensionCode
you can use the {clientClasses}
variable which generates a mapping dictionary for all generated client classes. The output will look like:
{"PersonController": PersonController, "CompanyController": CompanyController}
When using the AngularJS template you can use this variable to register all generated client classes as AngularJS services. To do so, add the following code to your ExtensionCode
:
var clientClasses = {clientClasses};
for (var clientClass in clientClasses) {
if (clientClasses.hasOwnProperty(clientClass)) {
angular.module('app').service(clientClass, ['$http', clientClasses[clientClass]]);
}
}
You can extend generated classes by adding class names to the ExtendedClasses
setting. The bodies of the extended classes are then copied into the generated classes. The external code can be defined in the "ExtensionCode" setting (the import of the generated classes must look as follows):
// Sample template: Angular2
import * as generated from "./apiClients";
class PersonsClient extends generated.PersonsClient {
public myNewMethod() {
}
}
You can customize the HTTP options or process each HTTP response. Use the settings "UseTransformOptionsMethod" or "UseTransformResultMethod" to enable the features. The then required "transformOptions" or "transformResult" methods can be implemented per client class ("ExtendedClasses" setting) or as a base class for all clients ("BaseClass" setting). The externally implemented "transformOptions(options)" method must return a promise which resolves to the transformed options (except for the JQuery templates, they require sync methods). The method parameters depend on the selected generator template (i.e. the used framework/library).
A sample for Angular 2 (the "BaseClass" setting is set to "ClientBase"):
// Sample template: Angular2
import * as generated from "./serviceClients";
import { RequestOptionsArgs } from '@angular/http'; // ignore
export class ClientBase {
protected transformOptions(options: RequestOptionsArgs) {
// TODO: Change options if required
console.log("HTTP call, options: " + JSON.stringify(options));
options.headers.append("myheader", "myvalue");
return Promise.resolve(options);
}
protected transformResult(url: string, response: Response, processor: (response: Response) => any) {
// TODO: Return own result or throw exception to change default processing behavior,
// or call processor function to run the default processing logic
console.log("Service call: " + url);
return processor(response);
}
}
The Angular2
, Fetch
and Aurelia
templates generate a protected jsonParseReviver
field which is passed to all JSON.parse() calls. This reviver field can only be set with an extension class. To do so, add your client class to the ExtensionClasses
array setting and implement the following ExtensionCode
(sample for the Fetch
template):
class GeoClient extends generated.GeoClientBase {
constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
super(baseUrl, http);
this.jsonParseReviver = (key: string, value: any) => {
return value; // TODO: Transform value if necessary
};
}
}