0

Hi I'm working with an API Where an employee can see his Vacation (overview and balance) and Request new Vacation. A manager can Approve or Reject a Request for Vacation. He can also create Vacation on behalf of an employee.

I'm in doubt what would be the best design. Most understandable for a developer (say mobile developer, consuming the API)

I have two main questions: 1) Should I expose VacationRequest as its own resource, or just as a specific state of a Vacation resource.

  1. /vacation/vacations/requests/preview (employee post to preview effect of a vacation request, employee_id is in request body, system returns vacation summary)
  2. /vacation/vacations/requests (employee post a vacation request, employee_id is in request body, system returns vacation summary)
  3. /vacation/vacations/preview (employee post to preview effect of new vacation with state= requested. etc.)
  4. /vacation/vacations (manager post vacation on behalf of employee)
  5. /vacation/vacations/{vacation_id}/approval (manager post approval of vacation for employee)

2) should I only have uri template like /vacation/vacations/{vacation_id} or would it be better to split into

  1. /vacation/vacations/{vacation_id} (used by manager)

  2. /vacation/employees/{employee_id}/vacations/{vacation_id} (used by employee)

  • 3
    Why do you have vacation/vacations in almost all of your identifiers? What's the duplication for? – Andy Aug 16 '17 at 7:41
  • How would the alternative to having VacationRequest actually look like? – larsbe Aug 16 '17 at 7:55
  • If an employee would perform a GET /vacation/vacations/, which vacations would be returned, only his own or all that he has the right to know about? Would that change if the employee got the "vacation approval" rights? – Bart van Ingen Schenau Aug 16 '17 at 9:35
  • @DavidPacker to indicate a top level domain – Christian Johansen Aug 18 '17 at 10:06
  • @larsbe Like in 3. Or what do you mean? – Christian Johansen Aug 18 '17 at 10:08
1

In terms of REST, especially if you apply the HATEOAS principle, it really doesn't care how you name your URL. The client should not really care about the URLs, as the server should generate the links for the client.

There are a few guidelines though, good REST URIs should be a noun, not a verb. URIs should address objects, rather than addressing methods.

REST API should have a limited number of general purpose verbs. Good HTTP REST API should use HTTP verbs correctly, for example use GET request for retrieval request and POST/PUT for data modification/creation request.

Some example of good REST URLs (either one to use is a matter of taste):

GET /employees/{employee_id}/vacations
GET /employees/{employee_id}?details=name,vacations

to obtains the list of vacations and vacation requests related to the employee with a given employee_id.

I think vacation requests should simply be vacations with status=pending, however if you decide that you want to expose vacation requests as separate resource, REST doesn't really prevent you from doing that either. As long as the server produces the URLs per HATEOAS, ultimately it doesn't really matter if it's exposed as separate URL.

As per HATEOAS, vacation list resources should contain a link (and form) to create vacation request, which may look like this:

POST /employees/{employee_id}/vacations

and a list of URLs that can be used to retrieve and update details about a vacation, which may look like this:

GET /vacation/{vacation_id} (for retrieving detail)
PUT /vacation/{vacation_id} (for updating detail)
PATCH /vacation/{vacation_id} (alternative for updating detail)
(important: update requests must be conditional request/If-Match to protect against concurrent update)

Non manager employees can only update pending vacation, if they attempt to update approved vacation, the vacation status should revert back to pending. Non-manager cannot modify the status field directly otherwise.

The manager that's responsible for approving the vacation of an employee have permission to set their vacation status to approved or rejected.

An employee can retract their vacation request by sending DELETE request:

DELETE /vacation/{vacation_id}

which would set the vacation status to retracted.

Note how all requests related to the same object are done against the same URL, but with different HTTP methods. This gives the client the context that these request all revolves around the same object. They can use this for example, to implement caching, to automatically invalidate the data cached for the same URL when making a POST/PUT/DELETE request to that URL.

  • Thx for taking the time to make an elaborate answer. I'm mostly interested in the particular design questions I posted, not a general recommendation on use of Http verbs. The most useful part is "I think vacation requests should simply be vacations with status=pending". But it lacks an explanation why you think so. – Christian Johansen Aug 25 '17 at 9:54
0

REST doesn't care what spelling you use for your resource identifiers. Users don't typically care either. Developers do -- identifier spellings are cousins to coding standards.

In your API, you should really be thinking about your resources as integration resources, rather than domain resources. What's the protocol for checking one's vacation balance? What's the protocol for updating the vacation balance for a report?

should I only have uri template like /vacation/vacations/{vacation_id} or would it be better to split

Separating out different identifiers for use cases that should be performed by different roles is a good idea, I think, as it should make securing the different end points easier.

Should I expose VacationRequest as its own resource, or just as a specific state of a Vacation resource

I would normally expect that all form submissions go to the same endpoint, with all of the required data in the message-body. It doesn't have to be that way, of course. The clients don't care. Your routing probably doesn't care very much. Authentication concerns might apply. It might be useful to have the request identifiers in your logs.

  • thx. for commenting Most use full point is "Separating out different identifiers for use cases that should be performed by different roles is a good idea" – Christian Johansen Aug 25 '17 at 9:56
  • Regarding form submission, I don't think that it should go to the same endpoint if you want to achieve a task based (not crud) design. For instance creating a nested resource /approval where post would approve or reject makes perfect sense. versus a crud update where state is set to either rejected or approved. And other parts of the resource might be updated at the same time. – Christian Johansen Aug 25 '17 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.