-1

You might have seen many post related to this title. But, I think, I have a different case where I need help. I tried to go thru several threads for my question but could not find any specific answer that I can go with confidence.

To explain, I want to publish a RESTful API that performs typical GET operation based on provided input details. This API is idempotent in nature and does not create, update or delete any resource. So, my ideal choice should be to use HTTP GET method in this case.

However, making things complex, my API will need a big JSON object with details as a part of the request to derive required information for the response. It is not advisable to put that JSON string in the request URI. Hence, I have to put that in request body itself. But, HTTP GET does not consider request body content. And, I don't want to (or don't know if I should) use HTTP POST or PUT for this API as the API is idempotent and does not create/modify any resource.

For now, I am more inclined towards using HTTP OPTIONS for this purpose, but I am not sure if this is something I should do considering RESTful standardization.

So, what do you suggest? Is it an acceptable usecase to use POST or OPTIONS in this case? Or, I should do something else?

For reference, below is the dummy sample of the request data object.

{
"parametersList": {
    "itemRange": {
        "code": "11",
        "start": 100683,
        "end": 168003
    },
    "dateRange": {
        "startDate": "2017-10-01",
        "endDate": "2017-10-31"
    },
    "market": {....},
    "startTimeRange": {...},
    "endTimeRange": {....},
    "serviceType": {....},
    "segmentType": {....},
    "daysOfWeek": {
        "days": ["MON", "WED", "THU", "FRI", "SAT", "SUN"]
    },
    "itemNumber": 0
}
}

The {...} in above example represents internal object structure that may vary based on the data.

ACloudRoamer
  • 1,043
  • 2
  • 11
  • 19
  • What's wrong with using `POST`? – Kayaman Nov 07 '17 at 21:02
  • As I know, as per the standard, a POST request makes any change in the resource state, mostly creates it. In my case, I don't do any change in the resources. It's purely a get operation. – ACloudRoamer Nov 07 '17 at 21:03
  • Yet you can't use `GET`. So the standard has failed you. Now it's up to you to decide whether you want to be limited by that (note that a "standard" is not a law), or solve your problem in a simple way. – Kayaman Nov 07 '17 at 21:07
  • Looks like you are trying to do something similar to GraphQL. See how it handles queries. – tsolakp Nov 07 '17 at 21:08
  • Before you sell yourself on it being impractical to take one approach over another, answer this question: what data are you passing across the wire, and how long will the total URI be? – Makoto Nov 07 '17 at 21:09
  • @Kayaman, I am with you on the ideology of "standard". My last bet will be to use POST only to make things work. With this question, I only want to ensure I am not doing something very wrong and if there is any better way to do this. Thanks! – ACloudRoamer Nov 07 '17 at 21:10
  • @Makoto, I am sending a big JSON object in the request containing data to derive the information required for the response of the service. The length of the request JSON object could be as big as over 1200 characters or more. Does this answer your question? – ACloudRoamer Nov 07 '17 at 21:12
  • [As long as you're under 2,000 characters, you should be fine.](https://stackoverflow.com/a/417184/1079354) Give us an example of the POST body you want to send, and the GET with query parameters you want to send. There may be a way to shorten the message in both cases to help you make an informed decision. – Makoto Nov 07 '17 at 21:14
  • @Makoto, The current example I have for the request object is of 1370 characters long. However, there are many internal objects null in this structure yet. So, the length of the object could go beyond 2000 if the object contains all possible elements. Hence, I am not much willing to take this chance of sending it using a query string parameter. Also, I would not be able to put the example of the JSON here as it contains proprietary confidential data. Anyways, thanks a lot for trying to help. – ACloudRoamer Nov 07 '17 at 21:30
  • ...So you can't even put a *sample* of data? I'm not looking to see anything sensitive. I just need a reference. If it's the case that your queries can actually be fixed so that you don't *need* to send a lot of data across the wire, then that's something I'd like to explore; having to send this much data just to one endpoint is a smell which is likely indicative of this work being best broken across multiple endpoints. – Makoto Nov 07 '17 at 21:37
  • @Makoto, I have added a sample request object in the question to give some idea. – ACloudRoamer Nov 07 '17 at 21:56
  • REST is just a generalization of the common Web we are used to in our daily lifes. Just think about how you would solve this issue using just plain HTML and than transfer this concept onto REST and there you go. I.e. you could create a query-resource first where you POST your payload to, start off a processing step, and passing back a lookup id (link in location header) and perform a lookup via GET later on using the returned link. While the generation of the resource is not cacheable itself, the retrieval using the returned lookup URI is – Roman Vottner Nov 07 '17 at 23:53
  • Btw, after reading most of the comments, POST has to be used if the semantics of the other operations don't apply for your task at hand. By definition, the semantics of a POST operation are defined by the implementor of the service and it can but does not have to create actual resources or change states at all. – Roman Vottner Nov 07 '17 at 23:59

3 Answers3

1

In such cases you should use POST. In general POST is used if no other method is applicable. OPTIONS has another purpose and cannot be used here.

POST is for example also used for large search queries where you specify search terms in the body

Another good example for using POST instead of GET is when you are sending sensitive data in the request.

also have a look at this article

and this question

niekname
  • 2,528
  • 1
  • 13
  • 27
  • I also thought so, but my only concern is that I don't create or update any resource as a part of this request. In that case, I am not sure using POST is a right choice as per standards. But, thanks for your input. – ACloudRoamer Nov 07 '17 at 21:08
  • I went thru the article you have posted here before posting this question. However, I missed to catch the rule "Rule #3: Use POST when dealing with long requests." It makes some sense now to use POST. – ACloudRoamer Nov 07 '17 at 21:16
  • 1
    Personally, I think it's premature to say one over the other until we have an idea of the shape of data being sent across. It could be that there are optimizations to be made in the query to begin with. – Makoto Nov 07 '17 at 21:19
  • @Makoto, as you have said, I did optimization in my request criteria to reduce the input length to a significant level. Now, as I am just left with few attributes, I have decided to pass them in query parameters. This will let me use a GET method without any doubt. Thank you! – ACloudRoamer Nov 08 '17 at 19:22
1

Go for POST, even if you manage to get it done with GET(creating a URI) its not the optimal solution as there might be cases when your GET request URL can become too long.

Moreover I didn't find any viable source discouraging the use of POST for querying with a valid reason.

POST(with some other security measures) is used for authentication as well, which does not create/modify any resource. So using it for your problem shall not be a bad practice.

Gaurav Arya
  • 146
  • 3
  • I am with you on this. I was planning to use POST finally. But, then I found I can do some optimization in my search criteria input values. So, now I am down with only few attributes, with which, I can use GET method for this service. Thanks. – ACloudRoamer Nov 08 '17 at 19:24
0

This is an interesting one because of your requirement to send a big JSON object.

A REST API endpoint that gets a resource should always use a GET endpoint with GET parameters. Is there a specific reason why you are trying to send a JSON object rather than sending parameters?

In the case that you insist on sending a JSON object, I have found examples of existing code that base64 encode the JSON object and then add it to a GET parameter. However please note that if you try to send a massive JSON object you could have issues with URL length. But it should never come to that. GET parameters on a restful API should always be simple and short. If you are sending too much data then there's something wrong with the design of the REST API and it needs to be thought through more carefully.

Ruben Funai
  • 629
  • 5
  • 5
  • My request contains a JSON string of a specific request object structure containing required information to derive the response. The content of the object is significant to get the right information in the response. And, as you have said, I am not much willing to send this JSON string in the query parameter of a GET request as the length of the string could be arbitrary. Thanks for your response. – ACloudRoamer Nov 07 '17 at 21:24