Jaden Korr
Jaden Korr

Reputation: 153

REST Check if resource exists, how to handle on server side?

how to handle resource checking on server side? For example, my api looks like:

/books/{id}

After googling i found, that i should use HEAD method to check, if resource exists. https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

I know, that i can use GET endpoint and use HEAD method to fetch information about resource and server does not return body in this case.

But what should i do on server side? I have two options.

  1. One endpoint marked as GET. I this endpoint i can use GET method to fetch data and HEAD to check if resource is available.

  2. Two endpoints. One marked as GET, second as HEAD.

Why i'm considering second solution? Let's assume, that GET request fetch some data from database and process them in some way which takes some time, eg. 10 ms

But what i actually need is only to check if data exists in database. So i can run query like

select count(*) from BOOK where id = :id

and immediately return status 200 if result of query is equal to 1. In this case i don't need to process data so i get a faster response time.

But... resource in REST is a object which is transmitted via HTTP, so maybe i should do processing data but not return them when i use HEAD method?

Thanks in advance for your answer!

Upvotes: 10

Views: 19647

Answers (3)

cassiomolin
cassiomolin

Reputation: 130877

You could simply delegate the HEAD handler to the existing GET handler and return the status code and headers only (ignoring the response payload).

That's what some frameworks such as Spring MVC and JAX-RS do.


See the following quote from the Spring MVC documentation:

@GetMapping — and also @RequestMapping(method=HttpMethod.GET), are implicitly mapped to and also support HTTP HEAD. An HTTP HEAD request is processed as if it were HTTP GET except but instead of writing the body, the number of bytes are counted and the " Content-Length header set.

[...]

@RequestMapping method can be explicitly mapped to HTTP HEAD and HTTP OPTIONS, but that is not necessary in the common case.

And see the following quote from the JAX-RS documentation:

HEAD and OPTIONS requests receive additional automated support. On receipt of a HEAD request an implementation MUST either:

  1. Call a method annotated with a request method designator for HEAD or, if none present,
  2. Call a method annotated with a request method designator for GET and discard any returned entity.

Note that option 2 may result in reduced performance where entity creation is significant.


Note: Don't use the old RFC 2616 as reference anymore. It was obsoleted by a new set of RFCs: 7230-7235. For the semantics of the HTTP protocol, refer to the RFC 7231.

Upvotes: 10

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57214

Your reference for HTTP methods is out of date; you should be referencing RFC 7231, section 4.3.2

The HEAD method is identical to GET except that the server MUST NOT send a message body in the response (i.e., the response terminates at the end of the header section).

This method can be used for obtaining metadata about the selected representation without transferring the representation data and is often used for testing hypertext links for validity, accessibility, and recent modification.

You asked:

resource in REST is a object which is transmitted via HTTP, so maybe i should do processing data but not return them when i use HEAD method?

That's right - the primary difference between GET and HEAD is whether the server returns a message-body as part of the response.

But what i actually need is only to check if data exists in database.

My suggestion would be to use a new resource for that. "Resources" are about making your database look like a web site. It's perfectly normal in REST to have many URI that map to a queries that use the same predicate.

Jim Webber put it this way:

The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources. In other words, the resources are part of the anti-corruption layer. You should expect to have many many more resources in your integration domain than you do business objects in your business domain.

Upvotes: 0

Łukasz Jakubek
Łukasz Jakubek

Reputation: 1013

Endpoint should be the same and server side script should make decision what to do based on method. If method is HEAD, then just return suitable HTTP code:

  • 204 if content exists but server don't return it
  • 404 if not exists
  • 4xx or 5xx on other error

If method is GET, then process request and return content with HTTP code:

  • 200 if content exists and server return it
  • 404 if not exists
  • 4xx or 5xx on other error

The important thing is that URL should be the same, just method should be different. If URL will be different then we talking about different resources in REST context.

Upvotes: 7

Related Questions