Integrating your Angular frontend with a Spring Boot backend can be a breeze if you automate the process of creating your Angular services. This post will show you how to leverage Gradle, OpenAPI (Swagger), and the OpenAPI Generator to generate type-safe Angular TypeScript services directly from your Spring Boot REST controllers, saving you time and reducing errors.

Why Automate?

Manually creating Angular services that interact with your Spring Boot REST API is tedious and error-prone. Keeping your frontend and backend synchronized can become a maintenance nightmare. Automation offers several key benefits:

  • Reduced Boilerplate: Say goodbye to writing repetitive HTTP requests and data mapping code.
  • Type Safety: Generated services provide type safety, catching errors at compile time rather than runtime.
  • Improved Maintainability: Changes to your API are reflected in your Angular services with minimal effort.
  • Enhanced Productivity: Focus on building features, not wiring up API calls.

Setting the Stage

We’ll use the following technologies:

  • Spring Boot: Our backend framework.
  • Springdoc OpenAPI: For generating the OpenAPI specification.
  • OpenAPI Generator: To generate the Angular TypeScript service.
  • Gradle: Our build automation tool.
  • Angular: Our frontend framework.

Step-by-Step Guide

  1. Spring Boot Dependencies:

Add the Springdoc OpenAPI dependency to your Spring Boot project’s build.gradle file:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc:2.0.2' // Or latest
    // ... other dependencies
}
  1. Configure OpenAPI (Optional):

Create a Spring Boot configuration class to customize your API documentation:

@Configuration
public class OpenAPIConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("Your API Title")
                        .version("1.0")
                        .description("Your API Description"));
                // Add servers, security, etc. as needed
    }
}
  1. Gradle Configuration for OpenAPI Generation:

Add a Gradle task to generate the OpenAPI specification:

task generateOpenApiSpec(type: JavaExec) {
    dependsOn bootJar // Or classes if you are not building a jar

    mainClass.set('org.springdoc.core.SwaggerCodegen')

    args = [
            '--output-spec', "${buildDir}/docs/openapi.json",
            '--format', 'json'
    ]

    classpath = sourceSets.main.runtimeClasspath
}

bootJar.finalizedBy generateOpenApiSpec // Or classes.finalizedBy generateOpenApiSpec

build.dependsOn generateOpenApiSpec // Optional: Include in the build process
  1. Gradle Configuration for Angular Service Generation:

Add the OpenAPI Generator plugin and configure it to generate the Angular service:

plugins {
    // ... other plugins
    id 'org.openapi.generator' version '6.6.0' // Or latest
}

// ... other configurations

openApiGenerate {
    generatorName = "typescript-angular" // or "typescript-axios"
    inputSpec = "${buildDir}/docs/openapi.json"
    outputDir = "${projectDir}/src/main/angular/api" // Path within your Angular project
    apiPackage = "com.example.api" // Optional
    modelPackage = "com.example.model" // Optional
    configOptions = [
            "provideHttpClient": "true", // Essential for Angular 14+
            "withInterfaces": "true" // Generate interfaces for models
    ]
}

openApiGenerate.dependsOn generateOpenApiSpec

sourceSets {
    main {
        // ... existing source sets
        def angularSrcDir = file("${projectDir}/src/main/angular/api")
        if (angularSrcDir.exists()) {
            output.dir angularSrcDir
        }
    }
}

compileJava.dependsOn openApiGenerate
  1. Run the Gradle Tasks:

Execute the following Gradle command:

./gradlew openApiGenerate

This will generate the openapi.json file and the Angular service in the specified directories.

  1. Integrate into Angular:

Import and use the generated service in your Angular components:

import { ProductService } from './api/services/product.service'; // Adjust path

@Component({
  // ...
})
export class MyComponent {
  constructor(private productService: ProductService) {}

  ngOnInit() {
    this.productService.getProduct(123).subscribe(product => {
      console.log(product);
    });
  }
}

Key Considerations

  • Path Adjustments: Double-check the paths in your build.gradle file, especially inputSpec and outputDir. The outputDir should be inside your Angular project.
  • Angular Project Setup: Ensure your Angular project is correctly configured.
  • provideHttpClient: This configuration option is crucial for Angular 14 and later.
  • withInterfaces: This option generates interfaces for your models, which is good practice.
  • IDE Integration: Refresh your IDE after running the Gradle task.

By automating the generation of Angular services from your Spring Boot REST API, you can significantly improve your development workflow. This approach reduces boilerplate, increases type safety, and simplifies maintenance, allowing you to focus on building great features. Give it a try and see the difference it makes in your project!


Discover more from GhostProgrammer - Jeff Miller

Subscribe to get the latest posts sent to your email.

By Jeffery Miller

I am known for being able to quickly decipher difficult problems to assist development teams in producing a solution. I have been called upon to be the Team Lead for multiple large-scale projects. I have a keen interest in learning new technologies, always ready for a new challenge.