Làm cách nào để thiết kế API REST để xử lý các hoạt động không phải CRUD?


11

Tôi đang cố gắng chuyển đổi một tập hợp các dịch vụ dựa trên SOAP sang API RESTful.

Tôi bắt đầu bằng cách xác định tài nguyên bằng cách phân tích tên hoạt động và tôi đã nhận được tài nguyên Subscription.

Khi tôi cần cập nhật trạng thái của thuê bao, tôi không thể đơn giản gửi POSTyêu cầu đến máy chủ, vì tôi không có quyền truy cập trực tiếp vào tài nguyên, nhưng tôi cần gọi một số thao tác theo kiểu RPC để cập nhật các thuộc tính của chúng. Ngoài ra, chỉ và chỉ khi tôi thay đổi trạng thái đăng ký thành "hoạt động", cần có thêm một cuộc gọi đến dịch vụ bên ngoài.

Trong những trường hợp này, cách thực hành tốt nhất để xử lý các hoạt động cơ bản là gì?

Giải pháp tôi đưa ra là sử dụng các tham số truy vấn, để nếu tôi cần gọi dịch vụ kích hoạt, tôi có thể sử dụng một cái gì đó như:

POST /subscriptions/{subscriptionid}/?activate=true

Xem xét rằng tôi không thể cập nhật trực tiếp các trường đối tượng Đăng ký của mình, có cách nào tốt nhất để xử lý loại chuyển đổi này không?

Cập nhật 1:

Tôi có thể đặt trong phần thân của yêu cầu POST của mình một số giá trị, ví dụ "trạng thái": "hoạt động"

và kiểm tra bên trong dịch vụ của tôi các hoạt động thích hợp sẽ được kích hoạt.


Ánh xạ lệnh của REST tới các động từ HTTP không thành công với các hoạt động phức tạp. Bạn tốt hơn hết là chỉ thực hiện một cuộc gọi kiểu RPC POST kích hoạtSubcrip / {id} sẽ không có ai nhầm lẫn với nó
Ewan

@Ewan Tôi không chắc điều này tuân thủ mô hình RESTful, nhưng tôi đã đưa ra một giải pháp khác: trong mã của tôi, tôi có thể gọi hoạt động theo kiểu RPC thích hợp theo tải trọng đầu vào (Tôi có thể chuyển trạng thái = hoạt động trong phần thân của yêu cầu bài viết của tôi, mã sẽ gọi mã kích hoạt)
Vektor88

1
Một bản cập nhật cho một tài nguyên hiện có như thế này phải là một VẤN ĐỀ và phần thân của truy vấn sau đó là một mô hình một phần của những gì bạn đang thay đổi. POST được cho là một yêu cầu tạo ra một tài nguyên. Sự khác biệt này, ngoài việc rõ ràng hơn với người dùng, sẽ giúp mã của bạn dễ dàng biết khi nào hoạt động này xảy ra thay vì một bài đăng tài nguyên.
Ông Cochese

1
@ Vektor88 Thông thường, nhưng đó là những hoạt động bình thường mà bạn cần vượt qua trong toàn bộ đại diện trạng thái tài nguyên. Trường hợp sử dụng này có vẻ giống như một bản cập nhật một phần, rất phù hợp với một PATCH.
Ông Cochese

1
@MrCochese POST không phải là idempotent.
JimmyJames

Câu trả lời:


8

Bạn cần xem bài nói chuyện này của Jim Webber.

Khi tôi cần cập nhật trạng thái của thuê bao, tôi không thể đơn giản gửi yêu cầu POST đến máy chủ, vì tôi không có quyền truy cập trực tiếp vào tài nguyên, nhưng tôi cần gọi một số thao tác theo kiểu RPC để cập nhật các thuộc tính của chúng. Ngoài ra, chỉ và chỉ khi tôi thay đổi trạng thái đăng ký thành "hoạt động", cần có thêm một cuộc gọi đến dịch vụ bên ngoài.

Hãy suy nghĩ "nhắn tin"; gửi tin nhắn đến tên miền của bạn, mô tả những gì bạn muốn xảy ra. Tác dụng phụ của thông báo là mô hình miền của bạn thực sự thay đổi trạng thái của nó. "Tài nguyên" là hàng đợi tin nhắn.

POST /subscriptions/{subscriptionid}/?activate=true

Việc đánh vần tên tài nguyên không quan trọng đối với máy móc; nhưng mọi người có xu hướng trở nên khó chịu khi các định danh bạn sử dụng thoát khỏi quy ước rằng tài nguyên là "danh từ".

Ngoài ra, chúng ta đang nói về một tài nguyên phụ thuộc vào /subscriptions/{subscriptionid}, do đó, quy ước (xem RFC 3986 ) yêu cầu thể hiện mối quan hệ đó với một đoạn đường dẫn, thay vì sử dụng phần truy vấn.

Vì vậy, những cách viết này có thể là hợp lý

POST /subscriptions/{subscriptionid}/messages
POST /subscriptions/{subscriptionid}/activations

1
Buổi

0

Nếu đó là cờ boolean để kích hoạt / hủy kích hoạt công cụ, tôi sẽ nói mặc định là sử dụng JSON:

POST /subscriptions/{subscriptionid}/
{
    format: 0,
    subscription: 
    {
        active: false
    }
}

Điều này dễ dàng được mở rộng nếu bạn muốn hỗ trợ nhiều thuộc tính hơn. Một cách tiếp cận khác là cho nó điểm cuối của chính nó:

POST /subscriptions/{subscriptionid}/active/
DELETE /subscriptions/{subscriptionid}/active/

Cá nhân, tôi sẽ chỉ sử dụng điều này nếu activetrạng thái của sự kiện này cần / có các thuộc tính mà sau đó bạn có thể chuyển / nhận trong JSON, như ID người dùng hoặc cài đặt.

Nếu nó không phải là giá trị boolean mà chỉ là một hành động mà bạn cần kích hoạt nhưng không cần / có bất kỳ phản hồi trạng thái nào (ngoại trừ 200 OK ngay lập tức), tôi sẽ sử dụng một điểm cuối như thế này để kích hoạt nó giống như RPC:

POST /subscriptions/{subscriptionid}/activate/

Khi nghi ngờ, hãy đọc điều này: http://www.vinaysahni.com/best-practices-for-a-paticsatic-restful-api#restful (xem "Còn những hành động không phù hợp với thế giới của hoạt động CRUD thì sao? ")


0

REST không hoạt động. Activatelà một động từ và không thể là một trạng thái, Activelà một trạng thái.

Vì RESTful không có chức năng, bạn không thể nói cho dịch vụ RESTful phải làm gì, nhưng bạn có thể thêm công việc cho hàng đợi của dịch vụ.

Xem cái này:

PUT /subscriptionQueue
subscriptionId={subscriptionId}
active=true

Yêu cầu này là RESTful và hỗ trợ tất cả các lợi ích của RESTful (như hiệu suất, axit ...)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.