简体   繁体   中英

validate REST endpoint design

REST endpoint design says: Not use verb

In an workflow-like create Employee which has multi-tab style like "Basic Details", "Educational Details", "Work Experience", etc... One first tab data is filled continue button is pushed resulting in an backend API call which just validates the detail in that tab and returns the list of validation errors if any or moves to next tab for the user to fill data. So basically this calls for validate API for each of the tabs with no intention of saving data. Now one thing that comes naturally is below:

POST /employee/basic/validate (removing api versioning details from endpoint for simplicity)

But using validate in API means verb. How to design then?

There's a separate flow where one can just save "basic details" of employee - so its like any normal API validate and save - so POST /employee/basic/ is good for that case.

REST endpoint design says: Not use verb

That's not a REST constraint - REST doesn't care what spellings you use for your resource identifiers.

All of these URL work , exactly the way that your browser expects them to:


Resources are generalizations of documents; the nature of the HTTP uniform interface is that we have a large set of documents, and a small number of messages that we can send to them.

So if you want a good resource identifier, the important thing to consider is the nature of the "document" that you are targeting with the request.

For instance, the document you are using to validate user inputs might be the validation policy ; or you might instead prefer to think of that document as an index into a collection of validation reports (where we have one report available for each input).

Seems that what you try to do in the end is to run your operation in dry-run mode.

My suggestion would be to add a dry-run option as request parameter for instance.

/employee/basic?dry-run=true

REST says that you should use standards like HTTP to achieve a uniform interface. There are no URL standards as far as I know, even OData says that its URL naming conventions are optional.

Another thing that the browser is a bad REST client. REST was designed for webservices and machine to machine communication, not for the communication of browsers with webapplications, which is sort of human to machine communication. It is for solving problems like automatically order from the wholesaler to fill my webshop with new items, etc. If you check in this scenario both the REST service and REST client are on servers and have nothing to do with the browser. If you want to use REST from the browser, then it might be better to use a javascript based REST client. So using the browser with HTML forms as a REST client is something extreme.

If you have a multitab form, then it is usually collected into a session in regular webapplications until it is finalized. So one solution is having a regular webapplication, which is what you actually have, since I am pretty sure you have no idea about the mandatory REST constraints described by Fielding. In this case you just do it as you want to and forget about REST.

As of naming something that does validation I would do something like POST /employee/basic/validation and return the validation result along with 200 ok . Though most validation rules like "is it a date", "is it a number", etc. can be done on the clients currently they can be done even in HTML . You can collect the input in a session on server or client side and save it in the database after finilazing the employee description.

As of the REST way I would have a hyperlink that describes all the parameters along with their validations and let the REST client make tabs and do the REST. At the end the only time it would communicate with the REST service is when the actual POST is sent. The REST client can be in browser and collect the input into a variable or cookies or localstorage with javascript, or the REST client can be on server and collect the input into a server side session for example. As of the REST service the communication with it must be stateless, so it cannot maintain server side session, only JWT for example where all the session data is sent with every request.

If you want to save each tab in the webservice before finalizing, then your problem is something like the on that is solved with the builder design pattern in programming. In that case I would do something like POST /employeeRegistrationBuilder at the first step, and which would return a new resource something like /employeeRegistrationBuilder/1 . After that I can do something like PUT/POST /employeeRegistrationBuilder/1/basics , PUT/POST /employeeRegistrationBuilder/1/education , PUT/POST /employeeRegistrationBuilder/1/workExperience , etc. and finalize it with PUT/POST /employeeRegistrationBuilder/1/finished . Though you can spare the first and the last steps and create the resource with the basics and finish it automagically after the workExperience is sent. Cancelling it would be DELETE /employeeRegistrationBuilder/1 , modifying previous tabs would be PUT/PATCH /employeeRegistrationBuilder/1/basics . Removing previous tabs would be DELETE /employeeRegistrationBuilder/1/basics .

A more general approach is having a sort of transaction builder and do something like this:

POST /transactions/ {type:"multistep", method: "POST", id: "/employee/"}
-> {id: "/transactions/1", links: [...]}
PATCH /transactions/1 {append: "basics", ...}
PATCH /transactions/1 {append: "education", ...}
PATCH /transactions/1 {remove: "basics", ...}
PATCH /transactions/1 {append: "workExperience", ...}
PATCH /transactions/1 {append: "basics", ...}
...
POST /employee/ {type: "transaction", id: "/transactions/1"}
-> /employee/123

With this approach you can create a new employee both in multiple steps or in a single step depending on whether you send actual input data or a transaction reference with POST /employee .

From data protection (GDPR) perspective the transaction can be the preparation of a contract, committing the transaction can be signing the contract.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM