How to Create REST with Spring-rest-2-ts and TypeScript

How to Create REST with Spring-rest-2-ts and TypeScript

In this post, we discuss a Spring REST TypeScript generator that creates models and services that reflect backend models and REST services. I would like to introduce how you can REST with Spring-rest-2-ts TypeScript generator.

If your development setup uses the Spring framework on the backend and Angular or React on the frontend side, you can experience the same benefits that we did. In this short article, I would like to introduce how you can REST with our spring-rest-2-ts TypeScript generator.

Examples

To get an idea of what spring-rest2ts generator can do, let's create a simple model and REST controller in Java, and we will show what will be generated in TypeScript

public class BaseDTO {
    private int id;
    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
    private Date updateTimeStamp;
 }

public class OrderDTO extends BaseDTO {
    private double price;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
    private LocalDateTime orderTimestamp;
}

Spring REST controller:

@Controller
@RequestMapping("api/order")
public class OrderCtrl {

    @PostMapping(consumes = {"application/json"}, produces = {"application/json"})
    @ResponseBody
    @ResponseStatus(HttpStatus.CREATED)
    public OrderDTO createOrder(@RequestBody OrderDTO entity) {
        return entity;
    }

    @RequestMapping(path = "/{id}", method = RequestMethod.GET, produces = {"application/json"})
    @ResponseBody
    public OrderDTO getOrder(@PathVariable int id) {
        return new OrderDTO();
    }

}

In TypeScript, for DTO classes, we get two interfaces with mapped inheritance, where each field is mapped to their respective TypeScript types:

export interface Base {
    id: number;
    updateTimeStamp: number;
}

export interface Order extends Base {
    price: number;
    /**
     *    pattern : dd-MM-yyyy hh:mm:ss
     */
    orderTimestamp: string;
}

As we see, if a field has Jackson annotation, it is taken into account. If not, its transformation is based on Java types to TypeScript mapping. There is support for Type names mapping. In Java, we see that there is OrderDTO by providing proper name mapper which cuts off postfix DTO and we get type Order

Observable Based Service

The mapping of model classes is quite easy to understand. What's more interesting is the mapping of Spring REST controllers for which, in TypeScript, there is a generated implementation to call endpoints. Such an approach hides under method names, paths, and parameters, so the code will be resistant to changes on the backend. What is more important is that we transform return types to selected web frameworks; for Angular 2+ there is a generated valid Angular service ready to use for injection:

@Injectable()
export class OrderService {
    httpService: HttpClient;

    public constructor(httpService: HttpClient) {
        this.httpService = httpService;
    }

    public createOrder(entity: Order): Observable<Order> {
        let headers = new HttpHeaders().set('Content-type', 'application/json');
        return this.httpService.post<Order>('api/order', entity, {headers});
    }

    public getOrder(id: number): Observable<Order> {
        return this.httpService.get<Order>('api/order/' + id + '');
    }

}

OrderService is generated for OrderCtrl. Here, the type name was also transformed by the type name mapper. If the REST API is not available on the same host as the web application, there is a possibility to configure baseURL, which could be a path prefix o entire host reference

Promise Based Service

For web frameworks that are using the Promise API generator, proper configuration is also able to generate a service class:

export class OrderService {
    baseURL: URL;

    public constructor(baseURL: URL = new URL(window.document.URL)) {
        this.baseURL = baseURL;
    }

    public createOrder(entity: Order): Promise<Order> {
        const url = new URL('/api/order', this.baseURL);

        return fetch(url.toString(), {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(entity)
        }).then(res => res.json());
    }

    public getOrder(id: number): Promise<Order> {
        const url = new URL('/api/order/' + id + '', this.baseURL);

        return fetch(url.toString(), {method: 'GET'}).then(res => res.json());
    }

}

Configuration

Due to the greater flexibility, TypeScript generator is configured by code; no configuration files are needed. This gives a possibility to easily extend generator in places where it is needed. Here is the simplest generator configurator:

    Rest2tsGenerator tsGenerator = new Rest2tsGenerator();

    // Java Classes filtering
    tsGenerator.setModelClassesCondition(new ExtendsJavaTypeFilter(BaseDTO.class));
    tsGenerator.setRestClassesCondition(new ExtendsJavaTypeFilter(BaseCtrl.class));

    // Java model classes converter setup
    JacksonObjectMapper jacksonObjectMapper = new JacksonObjectMapper();
    jacksonObjectMapper.setFieldsVisibility(JsonAutoDetect.Visibility.ANY);
    modelClassesConverter = new ModelClassesToTsInterfacesConverter(jacksonObjectMapper);
    modelClassesConverter.setClassNameMapper(new SubstringClassNameMapper("DTO", ""));
    tsGenerator.setModelClassesConverter(modelClassesConverter);

    // Spring REST controllers converter
    restClassesConverter = new SpringRestToTsConverter(new Angular4ImplementationGenerator());
    restClassesConverter.setClassNameMapper(new SubstringClassNameMapper("Ctrl", "Service"));
    tsGenerator.setRestClassesConverter(restClassesConverter);

    // set of java root packages for class scanning
    javaPackageSet = Collections.singleton("com.blueveery.springrest2ts.examples");
    tsGenerator.generate(javaPackageSet, Paths.get("../target/ts-code"));

Thank you for reading !

java typescript spring angular react

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

How native is React Native? | React Native vs Native App Development

Article covers: How native is react native?, React Native vs (Ionic, Cordova), Similarities and difference between React Native and Native App Development.

How to Install OpenJDK 11 on CentOS 8

What is OpenJDK? OpenJDk or Open Java Development Kit is a free, open-source framework of the Java Platform, Standard Edition (or Java SE).

Wondering how to upgrade your skills in the pandemic? Here's a simple way you can do it.

Corona Virus Pandemic has brought the world to a standstill. Countries are on a major lockdown. Schools, colleges, theatres, gym, clubs, and all other public

Top 10 Advanced Java and Spring Boot Courses for Full-Stack Java Developers

These are best online courses to learn Spring Boot, Advanced Java, Docker, React, Microservices, DEvops, and Angular to become full stack Java developer.

Install Angular - Angular Environment Setup Process

Install Angular in easy step by step process. Firstly Install Node.js & npm, then Install Angular CLI, Create workspace and Deploy your App.