Thiết kế API REST cho các trang web có trình hướng dẫn


11

Tôi có một trang web với định dạng wizard. Nút gửi API sẽ ở bước thứ 4 của trình hướng dẫn. Tuy nhiên tôi muốn dữ liệu được nhập sẽ được lưu trữ trong cơ sở dữ liệu trước khi chuyển sang bước tiếp theo trong trình hướng dẫn. Tôi cũng muốn API REST hoạt động cho các trang có một tab duy nhất.

Vì vậy, tôi đã thiết kế API để thực hiện một tham số truy vấn hành động = dự thảo hoặc gửi. Nếu hành động là dự thảo, chỉ một số lĩnh vực nhất định là bắt buộc. Nếu hành động được gửi, tất cả các trường là bắt buộc. Xác thực trong lớp dịch vụ của API REST sẽ được thực hiện dựa trên tham số truy vấn. Có vẻ như tôi đã chỉ định rõ ràng các mệnh đề if / other trong tài liệu. Đây có phải là một hình thức chấp nhận của thiết kế RESTful? Điều gì sẽ được thiết kế tốt nhất với những yêu cầu này?


3
Tại sao dữ liệu tạm thời cần được lưu trữ trong DB?
Dan1701

2
@ Dan1701: vì vậy bạn có thể tiếp tục trình hướng dẫn từ một máy khác. Khi điền vào các biểu mẫu dài, phức tạp, có thể mất vài ngày để hoàn thành tất cả dữ liệu cần thiết, vì người dùng có thể không có sẵn tất cả dữ liệu cần thiết hoặc người dùng có thể cần phải thu thập các tệp bổ sung để tải lên từ các địa điểm khác nhau. Nếu bạn có thể tiếp tục từ các thiết bị khác nhau, bạn có thể tải trình hướng dẫn để tải ảnh từ điện thoại di động và tiếp tục nhập một mô tả / đối số dài bằng bàn phím thực trên máy tính để bàn, v.v.
Lie Ryan

Trong trường hợp đó, tôi nghĩ câu trả lời của @ guillaume31 có ý nghĩa.
Dan1701

Câu trả lời:


7

Vì bạn muốn duy trì mọi thứ trên máy chủ giữa các bước của trình hướng dẫn, có vẻ hoàn toàn chấp nhận được khi xem mỗi bước là một tài nguyên riêng biệt. Một cái gì đó dọc theo những dòng này:

POST /wizard/123/step1
POST /wizard/123/step2
POST /wizard/123/step3

Bằng cách bao gồm các liên kết hypermedia trong phản hồi, bạn có thể thông báo cho khách hàng về những gì họ có thể làm sau bước này - tiến lên hoặc quay lại các bước trung gian, và không có gì cho bước cuối cùng. Bạn có thể xem một ví dụ về nó trong Hình 5 ở đây .


Tôi đang sử dụng Angular cho UI. Vì vậy, tôi không chắc máy nhà nước hữu ích đến mức nào. Nhưng tôi nghĩ tài nguyên dựa trên bước dường như có ý nghĩa hơn là quản lý một bảng khác. Ngoài ra, tôi sẽ có thể gửi mọi thứ trong một bước duy nhất. Sẽ cho nó một shot trên thiết kế này ngày hôm nay. Cảm ơn đã giúp đỡ.
TechCrunch

Không có gì. Nhân tiện, cách tiếp cận "hai bàn" không loại trừ lẫn nhau với điều này. Có một tài nguyên HTTP trên mỗi bước không quyết định mô hình đối tượng của bạn trên máy chủ ứng dụng, chứ chưa nói đến lược đồ cơ sở dữ liệu. Nó chỉ là một đại diện Web.
guillaume31

1
@TechCrunch Về cơ bản Guillaume có nghĩa là đối tượng / bảng biểu thị biểu mẫu có thể được chia thành các phần, trong đó một phần của mô hình được lưu ở mỗi bước. Trong thực tế, bạn chỉ có thể có mỗi "bước" là một hình thức cho một phần của toàn bộ mô hình . Và nếu bạn thực hiện phương pháp này, nó thực sự làm cho kiến ​​trúc cực kỳ đơn giản. Mỗi POST đến máy chủ sẽ (tạo hoặc) cập nhật cùng một mô hình và mỗi GET sẽ tải cùng một mô hình và mỗi bước sẽ là một hình thức để điền vào các trường có ý nghĩa về mặt ngữ nghĩa (thuộc về nhau). Và chỉ đơn giản là có một boolean trên mô hình cho in_progresshoặc draft.
Chris Cirefice

3

Tôi đã cần phải làm một cái gì đó tương tự một thời gian trước đây, và sau đây mô tả những gì chúng ta kết thúc với.

Chúng tôi có hai bảng, Item và UninishedItem. Khi người dùng điền dữ liệu vào trình hướng dẫn, dữ liệu sẽ được lưu trữ trong bảng UnlinishedItem. Ở mỗi bước của trình hướng dẫn, máy chủ sẽ xác thực dữ liệu được nhập trong bước đó. Khi người dùng kết thúc với trình hướng dẫn, trình hướng dẫn sẽ hiển thị biểu mẫu ẩn / chỉ đọc trong trang xác nhận hiển thị tất cả dữ liệu sẽ được gửi. Người dùng có thể xem lại trang này và quay lại bước liên quan để sửa lỗi. Khi người dùng hài lòng với các mục nhập của họ, người dùng nhấp vào gửi và trình hướng dẫn sau đó gửi tất cả dữ liệu trong các trường mẫu ẩn / chỉ đọc đến máy chủ API. Khi máy chủ API xử lý yêu cầu này, nó sẽ chạy lại tất cả các xác nhận mà nó đã thực hiện trong mỗi bước của trình hướng dẫn và thực hiện các xác nhận bổ sung không phù hợp với các bước riêng lẻ (ví dụ: xác thực toàn cầu, xác thực đắt tiền).

Ưu điểm của phương pháp hai bảng:

  • trong cơ sở dữ liệu, bạn có thể có các ràng buộc chặt chẽ hơn trên bảng Mục so với bảng UnlinishedItem; bạn không cần phải có các cột tùy chọn sẽ thực sự được yêu cầu khi trình hướng dẫn kết thúc.

  • Các truy vấn tổng hợp trên các Mục đã hoàn thành để báo cáo dễ dàng hơn vì bạn không cần phải nhớ để loại trừ các Phần chưa hoàn thành. Trong trường hợp của chúng tôi, chúng tôi không bao giờ cần thực hiện các truy vấn tổng hợp giữa Item và UnlinishedItems, vì vậy đây không phải là vấn đề.

Những bất lợi:

  • Nó dễ bị trùng lặp logic xác thực. Khung web mà chúng tôi đã sử dụng, Django, làm cho điều này trở nên dễ chịu hơn một chút khi chúng tôi sử dụng tính kế thừa mô hình với một chút ma thuật meta để thay đổi các ràng buộc mà chúng tôi cần phải khác nhau trong Item và UnlinishedItem. Django tạo ra hầu hết các cơ sở dữ liệu và xác thực mẫu từ mô hình và chúng ta chỉ cần hack trong một vài xác nhận bổ sung trên đầu trang.

Các khả năng khác tôi đã xem xét và tại sao chúng tôi không đi với họ:

  • lưu dữ liệu trong cookie hoặc bộ nhớ cục bộ: người dùng không thể tiếp tục gửi từ một thiết bị khác hoặc nếu họ xóa lịch sử trình duyệt của họ
  • lưu trữ dữ liệu chưa hoàn thành dưới dạng dữ liệu phi cấu trúc (ví dụ JSON) trên cơ sở dữ liệu hoặc kho dữ liệu thứ cấp: Tôi sẽ phải xác định logic phân tích cú pháp và không thể sử dụng xác thực mẫu / biểu mẫu tự động của Django.
  • thực hiện xác thực mỗi bước ở phía máy khách: Tôi sẽ phải sao chép logic xác thực giữa Python / Django và JavaScript.

1
+1 để chỉ ra các xác nhận hợp lệ trên các mô hình 'dự thảo' và các mô hình 'đã hoàn thành'; Tôi đã không nghĩ về điều đó, và đó là một điểm quan trọng cần được xem xét. Nếu không, bạn có thể có một loạt các ifbáo cáo kiểm tra trạng thái dự thảo trong suốt quá trình xác nhận của bạn, điều này sẽ không tốt. Mặc dù một số khung rất tinh vi như Ruby on Rails có thể đơn giản hóa đáng kể vấn đề đó nếu được thực hiện đúng.
Chris Cirefice

1

Tôi đã thực hiện điều này theo cách tương tự như hỗn hợp các giải pháp của @ guillauma31 và @Lie Ryan.

Dưới đây là các khái niệm chính:

  1. Có một trình hướng dẫn 3 bước có thể được duy trì một phần cho đến khi hoàn thành.
  2. Mỗi bước có tài nguyên riêng của nó (Eg .: /users/:id_user/profile/step_1, .../step_2vv)
  3. Trên mỗi bước, dữ liệu và trạng thái hoàn thành có thể được truy xuất thông qua các yêu cầu GET và được duy trì thông qua các yêu cầu PATCH.
  4. Mỗi tài nguyên có các quy tắc xác thực riêng cho dữ liệu đã nhập.
  5. Mỗi bước trả về một khóa phải được sử dụng trong đầu vào của bước tiếp theo để đảm bảo chuỗi. Sau khi được sử dụng hoặc một cái mới được tạo, mã thông báo này sẽ hết hạn.
  6. Bước cuối cùng, chúng ta có tất cả dữ liệu cần thiết trên cơ sở dữ liệu và màn hình xác nhận được hiển thị. Xác nhận này gọi một tài nguyên khác để đánh dấu dữ liệu là đầy đủ (ví dụ .../profile/confirm:). Tài nguyên này không cần phải nhận lại tất cả dữ liệu. Nó chỉ đánh dấu dữ liệu là chính xác và đầy đủ.
  7. Có một thói quen theo lịch trình sẽ xóa sạch các mục không hoàn chỉnh này có nhiều hơn một vài ngày.

Những kẻ ở phía trước phải chăm sóc các mã thông báo để có được dòng chảy qua lại của trình hướng dẫn hoạt động.

API không trạng thái và nguyên tử.

Để làm cho "trình hướng dẫn một bước" hoạt động với thiết lập này, bạn sẽ phải thay đổi một số thứ, như xóa luồng mã thông báo hoặc tạo tài nguyên để trả lại mã thông báo dựa trên loại trình hướng dẫn hoặc thậm chí chỉ tạo tài nguyên mới để điền vào một đơn cụ thể này thuật sĩ bước (như PUT /users/:id_user/profile/).

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.