Thay đổi Root API URL trong Spring Boot

Trong spring boot, mặc định root-api-url hay còn được gọi là context path có giá trị là (“/”). Nhưng hiện nay, các REST API thường có chuẩn dạng /api/{version}/ để có thể phân biệt được các phiên bản của api.

Cách làm này khá thuận lợi khi bạn nâng cấp hệ thống backend nhưng là vẫn muốn giữ hệ thống backend cũ đã chạy trước đó. Thì chúng ta có thể chỉnh sửa để nâng version api lên. Chẳng hạn như trước đây là /api/v1 thì giờ nâng lên /api/v2. Client có thể sử dụng cả 2 api này tuỳ vào nhu cầu của họ.

Cấu hình context path

Để thay đổi context path trpng spring boot, chúng ta có thể cấu hình thông qua server.servlet.context-path. Có nhiều cách để thiết lập thuộc tính này, chúng ta hãy xem xét từng cách một.

Sử dụng application.properties / yml

Cách đơn giản nhất để thay đổi context path là đặt thuộc tính trong tệp application.properties/yml:

server.servlet.context-path=/api/v1

Java System Property

Chúng ta cũng có thể đặt context path như một Java system property trước khi context được khởi tạo.

public static void main(String[] args) {
    System.setProperty("server.servlet.context-path", "/api/v1");
    SpringApplication.run(Application.class, args);
}

OS Environment Variable

Spring Boot cũng có thể dựa trên các biến môi trường hệ điều hành. Trên các hệ điều hành họ Unix, chúng ta có thể viết:

SERVER_SERVLET_CONTEXT_PATH=/api/v1

Trên Windows, lệnh đặt biến môi trường là:

set SERVER_SERVLET_CONTEXT_PATH=/api/v1

Biến môi trường trên dành cho Spring Boot 2.x.x, Nếu bạn đang sử dụng spring boot phiên bản 1.x.x, thì thay đổi SERVER_SERVLET_CONTEXT_PATH  thành SERVER_CONTEXT_PATH.

Command Line Arguments

Chúng ta cũng có thể đặt các thuộc tính động thông qua các đối số dòng lệnh:

java -jar app.jar --server.servlet.context-path=/api/v1

Java config

Ngoài ra chúng ta cũng có thể cấu hình context path thông qua các bean

@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
  webServerFactoryCustomizer() {
    return factory -> factory.setContextPath("/api/v1");
}

Đối với Spring boot 1.x.x chúng ta có thể tạo bean EmbeddedServletContainerCustomizer 

@Bean
public EmbeddedServletContainerCustomizer
  embeddedServletContainerCustomizer() {
    return container -> container.setContextPath("/baeldung");
}

Thứ tự ưu tiên

Với nhiều tùy chọn này cấu hình context path, chúng ta có thể có nhiều hơn một cấu hình cho cùng một thuộc tính.

Đây là thứ tự ưu tiên theo thứ tự giảm dần:

  • Java Config
  • Command Line Arguments
  • Java System Properties
  • OS Environment Variables
  • application.properties trong thư mục hiện tại
  • application.properties trong classpath (src/main/resources or the packaged jar file)

Giả sử có 2 cấu hình trong Java ConfigOS Environment Variables thì spring boot sẽ chọn Java Config làm kết quả cuối cùng cho context path.

Sai làm khi cấu hình context path

Trước đây, khi các thành viên trong nhóm của mình sử dụng spring boot để build hệ thống backend. Thì lúc này mọi người cũng thống nhất chia các api ra thành các version như /api/v1, api/v2/ api/vn. 

Tuy nhiên về chưa biết đến cách cấu hình context path, mọi người đã làm chày cuối như thế này.

Đầu tiên tại một ApiConfig chứa thông tin về context path.

public class ApiConfig {
    
    public static final String API = "/api/v1";
}

Sau đấy cứ mỗi controller mọi người sẽ cộng chuỗi với hằng số này để có được URL dạng api/v1/xxx

@RestController
@RequestMapping(ApiConfig.API +  "/book")
public class BookController {...}

Nhìn rất là óc chó phải không các bạn, nếu các bạn nào lở làm thì bỏ đi nhé. Cứ tưởng tượng mỗi lần change API lại phải vào sửa code trong ApiConfig là thấy hơi chuối rồi. Chỗ nào cũng có dạng @RequestMapping(ApiConfig.API + “url”) rất là khó chịu.

Kết bài

Qua bài viết ngắn này chúng ta đã biết cách cấu hình content path trong spring boot rồi phải không nào. Nhớ đừng làm như kiểu cho có như cách trên mà mình từng làm nhé =(.

Nguồn tham khảo

https://www.baeldung.com/spring-boot-context-path

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x