Skip to content

JAX RS Application

Vojtěch Habarta edited this page Feb 24, 2017 · 4 revisions

typescript-generator is able to process JAX-RS application:

  1. It can automatically discover JSON classes used in JAX-RS REST service to generate TypeScript declarations for them.
  2. It can also generate client class (or just interface) for JAX-RS REST service.

1. Class discovery from JAX-RS application

Class discovery is convenient way how to specify which classes should be processed.

For example from this REST resource class:

@Path("user")
public class UserResource {
    @GET
    public User getCurrentUser() {}
}

typescript-generator can discover JSON class User and generate TypeScript declaration for it.

Resource classes can either be found automatically or using JAX-RS application class.

Automatic JAX-RS application

Automatic way can be turned on using classesFromAutomaticJaxrsApplication parameter. Here is Maven configuration snippet:

<configuration>
    <classesFromAutomaticJaxrsApplication>true</classesFromAutomaticJaxrsApplication>
</configuration>

Specific application class

If automatic way doesn't work as needed you can configure specific Application class from which typescript-generator can get list of classes. In previous versions this could be configured using classesFromJaxrsApplication parameter but now Application class is also used when it is reached using classes or classPatterns parameter.

Example JAX-RS application:

public class TestApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        return new LinkedHashSet<Class<?>>(Arrays.asList(
                UserResource.class
        ));
    }
}

and snippet for Maven:

<configuration>
    <classes>
        <class>cz.habarta.TestApplication</class>
    </classes>
</configuration>

Application constructor

When application class is parsed it must have no-argument constructor which should not have any side-effects like communication with database, starting new threads etc.

If your application has constructor with parameters you can add second constructor (can be private) or second application (possibly with inheritance).

Application class doesn't have to derive directly from javax.ws.rs.core.Application, it can derive from some framework class like org.glassfish.jersey.server.ResourceConfig in Jersey.

Maven Guice conflict

If there is a guice version conflict between your application and typescript-generator-maven-plugin either

  1. remove guice initialization from no-argument constructor or
  2. add following dependency to the plugin.
<plugin>
    <groupId>cz.habarta.typescript-generator</groupId>
    <artifactId>typescript-generator-maven-plugin</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.sonatype.sisu</groupId>
            <artifactId>sisu-guice</artifactId>
            <version>3.2.6</version>
        </dependency>
    </dependencies>
</plugin>

2. JAX-RS application client

This feature provides convenient way how to use REST service from TypeScript. Typescript-generator generates client class with methods that has typed parameters and return types and make HTTP requests to particular URL path.

Client class for JAX-RS service can be generated using generateJaxrsApplicationClient configuration parameter.

Let's see example. For this resource:

@Path("people/{personId}")
private static class PersonResource {

    @PathParam("personId")
    protected long personId;

    @GET
    public Person getPerson() {
        return null;
    }

    @GET
    @Path("address/{addressId}")
    public Address getAddress(@PathParam("addressId") long addressId) {
        return null;
    }

}

following client class will be generated:

class RestApplicationClient {

    constructor(private httpClient: HttpClient) {
    }

    getPerson(personId: number): RestResponse<Person> {
        return this.httpClient.request({ method: "GET", url: `api/people/${personId}` });
    }

    getAddress(personId: number, addressId: number): RestResponse<Address> {
        return this.httpClient.request({ method: "GET", url: `api/people/${personId}/address/${addressId}` });
    }

}

Here is Maven example how to use this functionality:

<configuration>
    <outputFileType>implementationFile</outputFileType>
    <outputKind>module</outputKind>
    <classesFromAutomaticJaxrsApplication>true</classesFromAutomaticJaxrsApplication>
    <generateJaxrsApplicationClient>true</generateJaxrsApplicationClient>
</configuration>

HttpClient adapter

Generated client class delegates requests to some HttpClient adapter which is set in constructor and can be implemented using arbitrary HTTP API or library like XMLHttpRequest, jQuery, axios, Angular etc.

This is HttpClient interface definition:

interface HttpClient {
    request(requestConfig: { method: string; url: string; queryParams?: any; data?: any; }): RestResponse<any>;
}

This interface can be implemented in typescript-generator extension or in user code.

Note that you can create multiple instances of client class. This can be useful for example for tests running in Node.js where each client can have different logged-in user cookie or header.

Customization

Return type

Methods have RestResponse return type which is by default defined as:

type RestResponse<R> = Promise<R>;

This definition can be configured using restResponseType parameter.

Additional request options

Using restOptionsType parameter it is possible to pass additional options to request methods.

Customization example

Customization parameters can be combined with importDeclarations or referencedFiles parameter to use types from some library. Here is Maven example with customization for axios library:

<configuration>
    <outputFileType>implementationFile</outputFileType>
    <outputKind>module</outputKind>
    <classesFromAutomaticJaxrsApplication>true</classesFromAutomaticJaxrsApplication>
    <generateJaxrsApplicationClient>true</generateJaxrsApplicationClient>
    <importDeclarations>
        <import>import axios from "axios"</import>
        <import>import { AxiosRequestConfig, AxiosPromise } from "axios"</import>
    </importDeclarations>
    <restOptionsType>AxiosRequestConfig</restOptionsType>
    <restResponseType>AxiosPromise</restResponseType>
</configuration>

Interface for JAX-RS application

Instead of (or in addition to) client class it is also possible to generate TypeScript interface for JAX-RS application. This can be turned on using generateJaxrsApplicationInterface configuration parameter.

While client implementation can only be generated in implementation file (.ts) interface can be generated also in declaration file (.d.ts).

Clone this wiki locally