Skip to content

Latest commit

 

History

History
268 lines (211 loc) · 9.97 KB

README.md

File metadata and controls

268 lines (211 loc) · 9.97 KB

Build Status Coverity Scan Build Status codecov Tech Debt Maven Status Known Vulnerabilities Codacy Badge license

Quality Gate

spring-typescript-services

Generate TypeScript interfaces and Angular services from Spring annotated @RestControllers. Get strongly typed interfaces for your Spring Boot microservices in no time.

Basic example

Spring @RestController:

@TypeScriptEndpoint
@RestController
@RequestMapping("/api/v1/customers")
public class CustomerController {

    @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public CustomerListDTO getAllCustomers() { ... }
}

Generated Angular service (TypeScript interfaces not shown here):

@Injectable()
export class CustomerController {
    
    private get serviceBaseURL(): string {
        return this.serviceConfig.context + '/api/v1/customers';
    }
    ...

    constructor(private httpClient: HttpClient, private serviceConfig: ServiceConfig) { }

    /* GET */
    public getAllCustomersGet(): Observable<CustomerListDTO> {
        const url = this.serviceBaseURL + '';
        const params = this.createHttpParams({});

        return this.httpClient.get<CustomerListDTO>(url, {params: params})
          .catch(error: HttpErrorResponse) => this.onError(error));
    }
    ...
}

Features

  • Generate Angular services from Spring @RestControllers
    • Support of Angular >= 5 (RxJS >= 5.5)
  • Generate TypeScript interfaces to map types of your Spring endpoints
  • All HTTP methods supported via @RequestMapping or its shortcut annotations
  • Support for JSON producing endpoints (more coming)
  • Support for path variables (@PathVariable annotation)

Currently not supported:

  • Endpoints which do not produce JSON
  • Support for path parameters (@PathParam annotation)

Getting started

Just specify the dependency in your Maven or Gradle based build and annotate a Spring @RestController with @TypeScriptEndpoint. Your next compile will then generate TypeScript files for every method with a @RequestMapping (or any shortcut annotation) producing "application/json" (MediaType.APPLICATION_JSON_VALUE).

Maven

<dependency>
    <groupId>org.leandreck.endpoints</groupId>
    <artifactId>annotations</artifactId>
    <version>0.4.0</version>
    <scope>provided</scope> <!-- the annotations and processor are only needed at compile time -->
    <optional>true</optional> <!-- they need not to be transitively included in dependent artifacts -->
</dependency>
<!-- * because of spring-boot dependency handling they nevertheless get included in fat jars -->

If you are using the maven-compiler-plugin, add spring-typescript-services to annotationProcesserPaths within the plugin configuration:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    ...
    <configuration>
        <annotationProcessorPaths>
            <path>
                <groupId>org.leandreck.endpoints</groupId>
                <artifactId>annotations</artifactId>
                <version>0.4.0</version>
            </path>
            ...
        </annotationProcessorPaths>
        ...
    </configuration>
</plugin>

Gradle

compileOnly 'org.leandreck.endpoints:annotations:0.4.0'

Usage

If supported Spring @RestContollers were found, you will find the generated TypeScript files under ./target/generated-sources/.

All services are part of an Angular module called APIModule, which you only need to import within your own module. Currently you also need to manually include HttpClientModule from @angular/common/http:

@NgModule({
  ...
  imports: [
    ...
    APIModule.forRoot(),
    HttpClientModule
  ],
  ...
})
export class AppModule { }

See API for configuration options.

Known Issues

  • spring-typescript-services does not work with endpoints returning only a HTTP status code. Currently it does only generate TypeScript services for endpoints producing "application/json" (MediaType.APPLICATION_JSON_VALUE).
  • When working with IntelliJ: "Build Project" by default only does incremental builds. This might break consistency of the generated files when the annotation processor only receives a part of the Spring @RestControllers. Better rely on the output from Maven compile.
  • There might be some unused imports (e.g. from RxJS) in the generated TypeScript files. This potentially increases your bundle size by a tiny amount. Feel free to manually remove those imports.

API

Spring Boot Annotations

@TypeScriptEndpoint

Annotate your @RestController to generate a corresponding Angular service and interface files.

By default the Angular services will have the same name as the @RestController. You can overwrite this by specifying a custom name:

@TypeScriptEndpoint(value = "FooService")
public class FooController { }

You can provide your own <#FREEMARKER>-template to use for generating TypeScript files for this specific TypeScriptEndpoint. This overwrites any defaults. The default template is located at /org/leandreck/endpoints/templates/typescript/service.ftl.

@TypeScriptEndpoint(template = "/org/leandreck/endpoints/templates/typescript/custom.ftl")
public class FooController { }

@TypeScriptTemplatesConfiguration

Configure if and what method suffixes are used in the default templates or provide your own.

Disable suffixes:

@TypeScriptTemplatesConfiguration(useSuffixes = false)
public class FooController { }

Modify suffix based on HTTP method (e.g. replace suffixGet by suffixPost):

@TypeScriptTemplatesConfiguration(suffixGet = "GET")
public class FooController { }

Modify the TypeScript output by providing your own <#FREEMARKER>-templates. Have a look at the default ones org.leandreck.enpoints.templates.typescript.

@TypeScriptTemplatesConfiguration(apimodule = "/org/leandreck/endpoints/templates/typescript/custom.ftl")
public class FooController { }

Available options:

  • apimodule
  • enumeration
  • index
  • interface
  • endpoint

@TypeScriptIgnore

Methods or fields annotated with @TypeScriptIgnore will be ignored by the annotation processor.

Annotate methods in your @RestController if you do not want to include them in the generated Angular service. If applied to a field it is not included in the respective interface file.

@TypeScriptType

Annotate Fields with @TypeScriptType to specify a custom template or override default mappings.

@TypeScriptType("any")
private Foobar foo;

will result in

foo: any

Angular Module

APIModule.forRoot()

The APIModule optionally receives a ServiceConfig which you may use to further configure the generated services.

Modify your endpoint's base URL path:

APIModule.forRoot({ context: 'http://www.example.com/path/to/api' })

Enable debugging to get some console output:

APIModule.forRoot({ debug: true })

Provide your own error handler function:

APIModule.forRoot({ onError: (error) => Observable.throw('An API error occured:' + error.message) })

How does it work?

spring-typescript-services is a Java annotation processor to generate Angular services and TypeScript types to access your spring @RestControllers.

It generates a service.ts file for every with @TypeScriptEndpoint annotated class and includes functions for every enclosed public Java Method with a @RequestMapping producing JSON. The TypeScript files are generated by populating <#FREEMARKER>-template files. You can specify your own template files or use the bundled defaults.