Code Monkey home page Code Monkey logo

rest-client-generator's Introduction

rest-client-generator

Build Status NPM Version License

Generate REST endpoint client from Swagger or WADL for you project. Useful for typed languages such TypeScript and Dart. Currently support generation for platforms:

  • Angular6 TypeScript (via @angular/common/http)
  • Angular5 TypeScript (via @angular/common/http)
  • Angular2 TypeScript (via @angular/http)
  • Angular2 Dart
  • Dojo2 TypeScript

Features:

  • Request/response representation application/json is handled as interface
  • Mimetypes such as text/*, application/xml, etc. are handled as strings
  • Mimetype application/octet-stream is handled as File
  • Other mimetypes are handled as Blob
  • Translate date fields in response JSON to js Date object
  • Full support XSD schema types (xs:string, xs:number, xs:boolean, xs:datetime, etc.)
  • XSD schema enumeration handled as enum
  • XSD schema extension handled as object inheritance
  • Support fileupload in multipart/form-data

Installation

Install globally rest-client-generator

npm install --global rest-client-generator

Generate

From WADL

Get some WADL schema, for example app.wadl:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
    <grammars>
        <include href="app.xsd"/>
    </grammars>
    <resources base="http://localhost:8080/restapi/">
        <resource path="/auth">
            <resource path="/login">
                <method id="login" name="POST">
                    <request>
                        <param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="login" style="query" type="xs:string"/>
                        <param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="password" style="query" type="xs:string"/>
                    </request>
                    <response>
                        <representation mediaType="text/plain"/>
                    </response>
                </method>
            </resource>
            <resource path="/logout">
                <method id="logout" name="POST"/>
            </resource>
        </resource>
        <resource path="/person">
            <resource path="/user/{id}">
                <param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="id" style="template" type="xs:number"/>
                <method id="getPerson" name="GET">
                    <response>
                        <ns2:representation xmlns:ns2="http://wadl.dev.java.net/2009/02" xmlns="" element="person" mediaType="application/json"/>
                    </response>
                </method>
            </resource>
            <resource path="/user">
                <method id="createPerson" name="POST">
                    <request>
                        <ns2:representation xmlns:ns2="http://wadl.dev.java.net/2009/02" xmlns="" element="person" mediaType="application/json"/>
                    </request>
                </method>
            </resource>
        </resource>
    </resources>
</application>

WADL file include schema <include href="app.xsd"/> with request and response types, here is app.xsd:

<?xml version="1.0" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="person" type="person"/>
    <xs:complexType name="person">
        <xs:sequence>
            <xs:element name="id" type="xs:number"/>
            <xs:element name="firstName" type="xs:string"/>
            <xs:element name="lastName" type="xs:string"/>
            <xs:element name="birthDate" type="xs:date"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

For example, you have TypeScript project with Angular2, to generate client run:

rest-client-generator --output-file services.ts --platform angular2-ts app.wadl

From Swagger

If you don't have WADL schema, you can generate client from Swagger YAML or JSON. Alternative of upper mentioned WADL schema in Swagger is app.yaml:

swagger: '2.0'
info:
  version: v1
  title: Test API
host: 'localhost:8080'
basePath: /restapi
schemes:
  - http
tags:
  - name: auth
  - name: person
paths:
  /auth/login:
    post:
      tags:
        - auth
      summary: ''
      description: ''
      operationId: login
      produces:
        - text/plain
      parameters:
        - name: login
          in: query
          required: true
          type: string
        - name: password
          in: query
          required: true
          type: string
      responses:
        '200':
          description: OK
  /auth/logout:
    post:
      tags:
        - auth
      summary: ''
      description: ''
      operationId: logout
      responses:
        '200':
          description: OK
  /person/user/{id}:
    get:
      tags:
        - person
      summary: ''
      description: ''
      operationId: getPerson
      produces:
        - application/json
      parameters:
        - name: id
          in: path
          required: true
          type: integer
          format: int34
      responses:
        '200':
          description: OK
          schema:
            $ref: '#/definitions/Person'
  /person/user:
    post:
      tags:
        - person
      summary: ''
      description: ''
      operationId: createPerson
      consumes:
        - application/json
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/Person'
      responses:
        '200':
          description: OK
definitions:
  Person:
    type: object
    required:
      - id
      - firstName
      - lastName
      - birthDate
    properties:
      id:
        type: integer
        format: int32
      firstName:
        type: string
      lastName:
        type: string
      birthDate:
        type: string
        format: date

To to generate client run command:

rest-client-generator --output-file services.ts --platform angular2-ts app.yaml

Generated client

Lets watch your generated rest client services.ts

import ...

export const SERVICE_ROOT_URL = new InjectionToken<string>('service-root-url');
export const SERVICE_JSON_DATE_PATTERN = new InjectionToken<string>('service-json-date-pattern');
...
export interface Person {
    id: number;
    firstName: string;
    lastName: string;
    birthDate: Date;
}

@Injectable()
export class AuthService {
    constructor...
    public login(login: string, password: string): Observable<string> {
        ...
    }
    public logout(): Observable<void> {
        ...
    }
}

@Injectable()
export class PersonService {
    constructor...
    public getPerson(id: number): Observable<Person> {
        ...
    }
    public createPerson(_request: Person): Observable<string> {
        ...
    }
}

@NgModule({
    ...
    providers: [
        { provide: SERVICE_ROOT_URL, ... },
        { provide: SERVICE_JSON_DATE_PATTERN, ... },
        ...
        AuthService,
        PersonService
    ]
})
export class ServiceModule {
}

In your app you can change url of your REST api, with provide constant SERVICE_ROOT_URL:

bootstrap(AppComponent,[provide(SERVICE_ROOT_URL, { useValue='http://yourapp.com:80/restapi/' })]);

In JSON date types has string representation (ISO 8601). TypeScript is not able to recognize it and convert to Date object. Constant SERVICE_JSON_DATE_PATTERN is regular expression, which test all received strings, if they matched is converted to Date object.

Interface Person is type from schema app.xsd. Services AuthService and PersonService are resources from WADL app.wadl with they methods. HTTP call are asynchronous, so methods return Observable.

Usage

You have generated rest client in services.ts, first you must import service module to your application module.

import ...
import { ServiceModule } from './services';

@NgModule({
    imports: [
        ...
        ServiceModule
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

Now, you can enjoy your client :-)

import ...
import { AuthService } from './services';

@Component(...)
export class LoginComponent {
    private model: any = {};
    constructor(private authService: AuthService) {
    }
    login() {
        this.authService.login(this.model.username, this.model.password)
            .subscribe((token: string) => {
                console.log('successfully logged in, token: %s', token);
            }, (error: Error) => {
                console.error(error);
            });
    },
    logout() {
        this.authService.logout().subscribe();
    }
}
import ...
import { PersonService, Person } from '../services';

@Component(...)
export class PersonComponent {
    constructor(private personService: PersonService) {
    }
    doSomeStuff() {
        let id: number = 1000;
        this.personService.getPerson(id)
            .subscribe((person: Person) => {
                console.log('person with id %d is: %o', id, person);
            });

        let person: Person = {
            id: null,
            firstName: 'Derp',
            lastName: 'Derpington',
            birthdate: new Date('1980-05-08T09:25Z')
        };
        this.personService.createPerson(person)
            .subscribe((id: string) => {
                person.id = parseInt(id);
                console.log('created person: %o', person);
            });
    }
}

License

Apache 2.0

rest-client-generator's People

Contributors

0xflotus avatar cyphercodes avatar dzurikmiroslav avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

rest-client-generator's Issues

CamelCase pattern for endpoints and ignore words

I'm using rest-client-generator with my Spring Boot project. I want to generate a Typescript client for my Angular2 application.

The generation works so far but the naming looks rather weird sometimes. authorization-endpoint becomes:

export class AuthorizationendpointService {
  // ..
}

Two things would be nice:

  • It would be awesome to have it in CamelCase when words are separated with -
  • An option which would allow one to exclude certain patterns like -endpoint completely

E.g. user-item-endpoint should become UserItemService in the generated service.ts.

XSD attribute support

Add support XSD attribute. In JSON no matter if property are described as xs:attribute or xs:element, but XSL allow also this syntax...

Not able to generate. Getting below error

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: ts.formatting.RulesProvider is not a constructor.

I am getting this error with sample file provided on the npm package page itself.
I am using Angular vesrion 5.0 and [email protected]

There seems to be incomplete conversion of interfaces..

screen shot 2017-07-28 at 12 32 49

screen shot 2017-07-28 at 12 33 16

application.wadl/xsd0.xsd (as well as schema.xml) contains the expected constituents. and the interface generated shows no properties.

Also... This manifests itself in quite a few places... missing property names not copied over from schema.xml
screen shot 2017-07-28 at 12 45 19
screen shot 2017-07-28 at 12 45 57
screen shot 2017-07-28 at 12 50 09
screen shot 2017-07-28 at 12 50 20
I've zipped up the documents I used, so you can test against them as well.
Archive.zip

What could be cause of this? Error: self signed certificate/ ... 'DEPTH_ZERO_SELF_SIGNED_CERT'

For this kind of command:
rest-client-generator --output-file services.ts --platform angular2-ts https://unnamedurl.com:9000/tomcatapp/application.wadl
Getting:
Reading WADL from https://unnamedurl.com:9000/tomcatapp/application.wadl
{ Error: self signed certificate
at Error (native)
at TLSSocket. (_tls_wrap.js:1092:38)
at emitNone (events.js:86:13)
at TLSSocket.emit (events.js:185:7)
at TLSSocket._finishInit (_tls_wrap.js:610:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:440:38) code: 'DEPTH_ZERO_SELF_SIGNED_CERT' }

=

No idea why I got the certificate errors. Maybe something wrong with the Tomcat server configuration.

=
It was likely there would have been an issue, because I'd not supplied a basic authentication header too.

=

I worked around this by downloading to local machine..

  1. application.wadl
  2. schema.xml.
  3. xsd0.xsd

On my Mac, I had to also go into System Preferences > Security & Privacy to allow VSCode to open application.wadl.
In the grammers node I modified:
<include href="application.wadl/xsd0.xsd">
to become:
<include href="xsd0.xsd">

Then I ran it on a local file in folder.
I was just expecting interfaces.
Having services generated as well was a very pleasant welcome bonus.
Useful project. Many thanks for your efforts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.