/spring-api

Library that aims for simplifying code for managing REST API written with Spring Framework. It helps to stick to certain conventions and good practices, simplifies API versioning. Supports servlet and reactive APIs.

Primary LanguageJavaApache License 2.0Apache-2.0

Spring API


Explore the docs »

Report a Bug · Request a Feature · Ask a Question

CI Last Commit Commit activity Project license

Pull Requests welcome

Table of Contents

✨ About

Spring API is a library that aims for simplifying code for managing REST API written with Spring Framework. It helps to stick to certain conventions and good practices, simplifies API versioning.

💡 Motivation

A lot of projects have challenges in unifying approach to building API, especially those which are complex or based on microservices. Goal of this library is to:

  • get rid of boilerplate code and magic strings in endpoints' declarations
  • simplify and unify how API is versioned
  • unify overall API declaration and endpoint paths

🔥 Features

  • apply prefix to all endpoints
  • version API in path or content type
  • configure base API context (useful especially in microservices)
  • provide default endpoint names when not set explicitly
  • handy utilities removing boilerplate code used to define endpoints with Spring
  • support both "standard" Servlet-based API as well as Reactive API
  • support OpenAPI 3.0 generation using SpringDoc library

🚀 Getting Started

This library works with Java 17 and Spring Boot 3 / Spring Framework 6. It is preferred to use spring-api-starter with Spring Boot.

When starter is used, it automatically detects whether you are using webmvc (servlet approach) or webflux (reactive approach). Additionally, it automatically configure SpringDoc OpenAPI generation when it detects SpringDoc is being used.

  1. Add dependency:

    • Maven:
        <dependency>
            <groupId>io.github.filipowm</groupId>
            <artifactId>spring-api-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
    • Gradle:
      implementation 'io.github.filipowm:spring-api-starter:2.0.0'
  2. To customize library configuration, check 🔧 Configuration Properties section.

  3. Use @Api, @ApiVersion annotations to leverage library features. You can still use Spring annotations and mix controllers annotated with @Api and @RestController. @Api is a replacement for both @RestController and @RequestMapping and enables this library features.

To define a version of endpoints within controller you can use either:

@Api(value = "/hello", version = @ApiVersion(2))

or

@Api(value = "/hello")
@ApiVersion(2)

Examples:

These examples use default Spring API configuration.

  • following snippet would generate GET /api/v1/hello endpoint returning 200 OK status

    @Api
    class HelloController {
        @GetMapping
        String get() { 
            return "Hello World";
        }
    }
  • following snippet would generate POST /api/v2/my-awesome-api/hi endpoint returning 202 Accepted status

    @Api("/my-awesome-api")
    @ApiVersion(2)
    class HelloController {
        @Accepted
        @PostMapping("hi")
        String get() {
            return "Hello World";
        }
    }
  • following snippet would generate GET /api/v2/awesome/my-api and GET /api/v3/awesome/my-api endpoints returning 200 OK status

    @Api(value = "/my-api", baseContext = "awesome", version = @ApiVersion(2))
    class HelloController {
    
        @GetMapping
        String get() {
            return "v2 Hello World";
        }
        
        @Ok
        @GetMapping
        @ApiVersion(3)
        String getNew() {
            return "v3 Hello World";
        }
    }

🔧 Configuration properties

Configuration properties use standard Spring Boot approach to defining properties.

Property Description Default value
spring.api.pathPrefix Prefix applied to all endpoints using @Api annotation, e.g. when set to /rest/ resulting path may be /rest/v1/hello. /api
spring.api.baseContext Context used after prefix and version in path. It can be used to make endpoints unique between microservices, or just use it to fulfill any other needs, e.g. when set to billing, all path may look like /api/v1/billing/hello. ``
spring.api.versioning.enabled Flag whether API versioning should be enabled. When enabled, you can version API using @ApiVersion annotation. Otherwise using it does not take any effect and paths may look like /api/hello instead of /api/v3/hello. true
spring.api.versioning.versionPrefix Prefix applied to API version number, e.g. if set to ver resulting path may be /api/ver1/hello or content type: application/ver1+json when content type versioning is used. v
spring.api.versioning.versionInContentType Flag whether API should be versioned using Content-Type HTTP header. When enabled, API is versioned using Content-Type header instead of URI path. false
spring.api.versioning.contentTypeVnd Definition of vendor-specific MIME type applied to Content-Type HTTP header, e.g. when set to vnd.app resulting content type may be application/vnd.app.v1+json, depending on defined consumes property in @Api annotation. When empty, resulting content type may be text/v1+html. ``

Example:

spring:
  api:
    pathPrefix: "/rest"
    baseContext: "/warehouse"
    versioning:
      enabled: true
      versionPrefix: v
      versionInContentType: false
      contentTypeVnd:

Using this configuration endpoints may look like /rest/v2/warehouse/hello.

Future plans

  1. Detect endpoints collisions and block application from starting.
  2. Allow using contentTypeVnd independently of content type versioning.

If you see a need to other features, please create an issue.