gabaros
gabaros

Reputation: 763

Allow only GET in REST API

I'm developing a REST API. I need a way to get all Countries, to allow the user to select several and save an application configuration.

I'm thinking in a resource with just a GET option, since INSERT/UPDATE/DELETE are not allowed. Does it make sense?.

In general, what is the best way to provide read-only access to data?, e.g. bind a select with countries or cities or whatever data need.

Edited:

It is not related to any specific framework. The API does allow CRUD operation, in some situations I need to provide read-only access, e.g. in a form to allow the user to select a country. That form is part of a CRUD operation, but I need the countries to bind a select input so the user can select them, so the way to get all countries is to provide a url(resource) to get them.

If that helps, besides the API I'm designing the user interface of the application who will consume it. Hence I need a way to extract all countries to let the user select them and save the form. The saving of the form is a POST to a resource which have a country field(attribute).

Upvotes: 3

Views: 6278

Answers (4)

Markon
Markon

Reputation: 4610

From my understanding, what you want to do is something like:

Request:

GET api.domain.com/countries

Response:

{  
"US": {
  "url": "api.domain.com/countries/us",
  "name": "US",
  "continent": "America",
  "others": "..."
},
"UK": {
  "url: "api.domain.com/countries/uk",
  "...."
}
...

Keeping it as simple as possible is OK (with just name/id). You fetch the whole list via your javascript application and let the user choose specific countries.

Afterwards, you can POST to another resource, like:

POST api.domain.com/user/1/countries
{
 "user": "api.domain.com/user/1",
 "countries": [
  "api.domain.com/countries/us", 
  "api.domain.com/countries/it"
 ] 
}

And with this action you can save your resource. This to me sounds totally fine. Please, don't use GET to save resources, edit data or do something like that.

Upvotes: -1

hspandher
hspandher

Reputation: 16753

REST does not say that you need to define all crud operations. If you want to provide only read-only access to a particular resource, then in no way it violates REST principle. The important thing is your GET should be idempotent, if that is not the case and GET request is changing the state of the resource in some way, than you are definitely defying REST. In that case you need to use POST request.

One more thing you need to ensure that other requests (POST, PUT, DELETE etc.) to that resource should raise 405(Method Not allowed) status code.

Besides there is reasonable probability that you'd want to use caching for country info GET request (both HTTP and internal caching), so in my opinion your design is accurate.

Upvotes: 0

Robert
Robert

Reputation: 1316

inf3rnos comment, even its short is the correct answer:
You don't have to allow every HTTP method a.k.a verbs (see list of the standard ones or longer list here) on an entity. I would go even further: I think I never have seen any real life API with all HTTP methods allowed on any entity, so excluding them is not problem.

There is even a HTTP method called OPTIONS (see http method overview or longer explanation), so clients can check which methods are allowed/possible on an entity.
Sitenote: Your framework will most likely build this method on its own for you.

So only allowing GET on an entity is completely ok and standard procedure. "Famous" examples are e.g. PayPal refunds or Facebook friendlists and there lots more if you just search for random REST APIs.


There is just one part in your question, I am concerned about:

I'm developing a REST API. I need a way to get all Countries, to allow the user to select several and save an application configuration.

I hope that's just additional information and not related to the planned GET requests, because GET should never "do any action" (e.g. "saving", "selecting" as the HTTP specs state:

[...] the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval.

Upvotes: 2

Stéphane GRILLON
Stéphane GRILLON

Reputation: 11872

If you use JAX-RS (RESTeasy, Jersey,...), you need use this annotation: @GET

If you use Spring MVC you need use this annotation: method = RequestMethod.GET

Example:

@RequestMapping(value = "/xxxxx/yyyyy/{zzzzz}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)

if you need use UPDATE/DELETE/POST by an admin you can use Spring Security

Example:

@RolesAllowed({ AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER })

Upvotes: 0

Related Questions