JAX-RS chỉ là một API!

1. Khái quát chung

Mô hình REST đã xuất hiện được vài năm và nó vẫn đang nhận được rất nhiều sự chú ý.

Một API RESTful có thể được triển khai trong Java theo một số cách: bạn có thể sử dụng Spring, JAX-RS hoặc bạn có thể chỉ viết các servlet thô của riêng mình nếu bạn đủ giỏi và dũng cảm. Tất cả những gì bạn cần là khả năng hiển thị các phương thức HTTP - phần còn lại là tất cả về cách bạn tổ chức chúng và cách bạn hướng dẫn khách hàng khi thực hiện lệnh gọi tới API của bạn.

Như bạn có thể hiểu từ tiêu đề, bài viết này sẽ đề cập đến JAX-RS. Nhưng “chỉ một API” nghĩa là gì? Có nghĩa là trọng tâm ở đây là làm rõ sự nhầm lẫn giữa JAX-RS và các triển khai của nó và đưa ra một ví dụ về ứng dụng web JAX-RS thích hợp trông như thế nào.

2. Bao gồm trong Java EE

JAX-RS không gì khác hơn là một đặc tả, một tập hợp các giao diện và chú thích được cung cấp bởi Java EE. Và sau đó, tất nhiên, chúng tôi có các triển khai; một số được biết đến nhiều hơn là RESTEasy và Jersey.

Ngoài ra, nếu bạn quyết định xây dựng một máy chủ ứng dụng tuân thủ JEE, các nhân viên của Oracle sẽ cho bạn biết rằng, trong số nhiều thứ khác, máy chủ của bạn nên cung cấp triển khai JAX-RS cho các ứng dụng đã triển khai để sử dụng. Đó là lý do tại sao nó được gọi là Nền tảng phiên bản doanh nghiệp Java .

Một ví dụ điển hình khác về đặc tả và triển khai là JPA và Hibernate.

2.1. Chiến tranh hạng nhẹ

Vậy tất cả những điều này giúp ích gì cho chúng ta, các nhà phát triển? Sự trợ giúp là ở chỗ các tệp triển khai của chúng tôi có thể và phải rất mỏng, cho phép máy chủ ứng dụng cung cấp các thư viện cần thiết. Điều này cũng áp dụng khi phát triển RESTful API: cấu phần cuối cùng không được chứa bất kỳ thông tin nào về việc triển khai JAX-RS đã sử dụng.

Chắc chắn, chúng tôi có thể cung cấp cách triển khai (đây là hướng dẫn cho RESTeasy). Nhưng sau đó chúng tôi không thể gọi ứng dụng của mình là “ứng dụng Java EE” nữa. Nếu ngày mai ai đó đến và nói “ Ok, đã đến lúc chuyển sang Glassfish hoặc Payara, JBoss trở nên quá đắt! “, Chúng tôi có thể làm được, nhưng đó không phải là một công việc dễ dàng.

Nếu chúng tôi cung cấp cách triển khai của riêng mình, chúng tôi phải đảm bảo máy chủ biết loại trừ tệp riêng của nó - điều này thường xảy ra bằng cách có tệp XML độc quyền bên trong tệp có thể triển khai. Không cần phải nói, một tệp như vậy phải chứa tất cả các loại thẻ và hướng dẫn mà không ai không biết gì về nó, ngoại trừ các nhà phát triển đã rời công ty ba năm trước.

2.2. Luôn biết máy chủ của bạn

Chúng tôi đã nói rằng chúng tôi nên tận dụng nền tảng mà chúng tôi cung cấp.

Trước khi quyết định sử dụng một máy chủ, chúng ta nên xem việc triển khai JAX-RS (tên, nhà cung cấp, phiên bản và các lỗi đã biết) mà nó cung cấp, ít nhất là cho môi trường Sản xuất. Ví dụ, Glassfish đi kèm với Jersey, trong khi Wildfly hoặc Jboss đi kèm với RESTEasy.

Tất nhiên, điều này có nghĩa là dành một ít thời gian cho việc nghiên cứu, nhưng nó chỉ được thực hiện một lần, khi bắt đầu dự án hoặc khi di chuyển nó sang một máy chủ khác.

3. Một ví dụ

Nếu bạn muốn bắt đầu chơi với JAX-RS, con đường ngắn nhất là: có một dự án ứng dụng web Maven với phần phụ thuộc sau trong pom.xml :

 javax javaee-api 7.0 provided  

Chúng tôi đang sử dụng JavaEE 7 vì đã có rất nhiều máy chủ ứng dụng triển khai nó. Lọ API đó chứa các chú thích mà bạn cần sử dụng, nằm trong gói javax.ws.rs . Tại sao phạm vi được “cung cấp”? Bởi vì jar này cũng không cần phải ở trong bản dựng cuối cùng - chúng tôi cần nó tại thời điểm biên dịch và nó được cung cấp bởi máy chủ trong thời gian chạy.

Sau khi phần phụ thuộc được thêm vào, trước tiên chúng ta phải viết lớp entry: một lớp rỗng mở rộng javax.ws.rs.core.Application và được chú thích bằng javax.ws.rs.ApplicationPath:

@ApplicationPath("/api") public class RestApplication extends Application { } 

Chúng tôi đã xác định đường dẫn vào là being / api. Bất kỳ đường dẫn nào khác mà chúng tôi khai báo cho các tài nguyên của mình, chúng sẽ có tiền tố là / api .

Tiếp theo, hãy xem một tài nguyên:

@Path("/notifications") public class NotificationsResource { @GET @Path("/ping") public Response ping() { return Response.ok().entity("Service online").build(); } @GET @Path("/get/{id}") @Produces(MediaType.APPLICATION_JSON) public Response getNotification(@PathParam("id") int id) { return Response.ok() .entity(new Notification(id, "john", "test notification")) .build(); } @POST @Path("/post/") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response postNotification(Notification notification) { return Response.status(201).entity(notification).build(); } }

Chúng tôi có một điểm cuối ping đơn giản để gọi và kiểm tra xem ứng dụng của chúng tôi có đang chạy hay không, GET và POST cho Thông báo (đây chỉ là một POJO với các thuộc tính cộng với getters và setters).

Triển khai cuộc chiến này trên bất kỳ máy chủ ứng dụng nào triển khai JEE7 và các lệnh sau sẽ hoạt động:

curl //localhost:8080/simple-jaxrs-ex/api/notifications/ping/ curl //localhost:8080/simple-jaxrs-ex/api/notifications/get/1 curl -X POST -d '{"id":23,"text":"lorem ipsum","username":"johana"}' //localhost:8080/simple-jaxrs-ex/api/notifications/post/ --header "Content-Type:application/json"

Trong đó simple-jaxrs-ex là gốc ngữ cảnh của ứng dụng web.

Điều này đã được thử nghiệm với Glassfish 4.1.0 và Wildfly 9.0.1.Final. Xin lưu ý rằng hai lệnh cuối cùng sẽ không hoạt động với Glassfish 4.1.1 do lỗi này. Rõ ràng đây là một vấn đề đã biết trong phiên bản Glassfish này, liên quan đến việc tuần tự hóa JSON (nếu bạn phải sử dụng phiên bản máy chủ này, bạn sẽ phải tự quản lý việc sắp xếp JSON)

4. Kết luận

Ở cuối bài viết này, chỉ cần lưu ý rằng JAX-RS là một API mạnh mẽ và hầu hết (nếu không phải tất cả) những thứ bạn cần đã được máy chủ web của bạn triển khai. Không cần phải biến có thể triển khai của bạn thành một đống thư viện không thể quản lý được.

Bài viết này trình bày một ví dụ đơn giản và mọi thứ có thể phức tạp hơn. Ví dụ, bạn có thể muốn viết các thống đốc của riêng mình. Khi cần, hãy tìm các hướng dẫn giải quyết vấn đề của bạn với JAX-RS, không phải với Jersey, Resteasy hoặc triển khai cụ thể khác. Rất có thể vấn đề của bạn có thể được giải quyết bằng một hoặc hai chú thích.