285

I need to invoke a process which doesn't require any input from the user, just a trigger. I plan to use POST /uri without a body to trigger the process. I want to know if this is considered bad from both HTTP and REST perspectives?

nyarasha
  • 1,119
  • 1
  • 14
  • 24
Suresh Kumar
  • 11,241
  • 9
  • 44
  • 54
  • 8
    Thanks everyone for your suggestions. Though everybody gave similar suggestion i.e. it is okay to POST with zero content, I am selecting Darrel's answer as correct due to the link to IETF discussion. The discussion clarifies a lot. – Suresh Kumar Nov 18 '10 at 02:15

6 Answers6

263

I asked this question on the IETF HTTP working group a few months ago. The short answer is: NO, it's not a bad practice (but I suggest reading the thread for more details).

Gerard Bosch
  • 648
  • 1
  • 7
  • 18
Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • 25
    Any updated source that would confirm that 10 years later? – Baptiste Pernet Apr 23 '20 at 21:59
  • damn my bad I misunderstood the answer because the double negative @TripeHound, I've deleted my comment – buncis Feb 16 '21 at 17:27
  • 5
    @BaptistePernet [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.3.3) contains essentially the same definition of POST as the version quoted in the linked thread; that RFC references [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.3.2) which says of `Content-Length` "_For example, a Content-Length header field is normally sent in a POST request even when the value is 0 (indicating an empty payload body)._" with no admonishment against doing so. Both are from 2014, so _slightly_ more up-to-date, but don't appear to be (relevantly) superseded (RFC 8615 doesn't seem to apply). – TripeHound Feb 16 '21 at 17:35
110

Using a POST instead of a GET is perfectly reasonable, since it also instructs the server (and gateways along the way) not to return a cached response.

Adam Vandenberg
  • 19,991
  • 9
  • 54
  • 56
77

POST is completely OK. In difference of GET with POST you are changing the state of the system (most likely your trigger is "doing" something and changing data).

I used POST already without payload and it "feels" OK. One thing you should do when using POST without payload: Pass header Content-Length: 0. I remember problems with some proxies when I api-client didn't pass it.

manuel aldana
  • 15,650
  • 9
  • 43
  • 50
20

If you use POST /uri without a body it is something like using a function which does not take an argument .e.g int post (void); so it is reasonable to have function to your resource class which can change the state of an object without having an argument. If you consider to implement the Unix touch function for a URI, is not it be good choice?

David Klempfner
  • 8,700
  • 20
  • 73
  • 153
yadab
  • 2,063
  • 1
  • 16
  • 24
3

Yes, it's OK to send a POST request without a body and instead use query string parameters. But be careful if your parameters contain characters that are not HTTP valid you will have to encode them.

For example if you need to POST 'hello world' to and end point you would have to make it look like this: http://api.com?param=hello%20world

marko982
  • 156
  • 6
2

Support for the answers that POST is OK in this case is that in Python's case, the OpenAPI framework "FastAPI" generates a Swagger GUI (see image) that doesn't contain a Body section when a method (see example below) doesn't have a parameter to accept a body.

the method "post_disable_db" just accepts a path parameter "db_name" and doesn't have a 2nd parameter which would imply a mandatory body.

@router.post('/{db_name}/disable',
             status_code=HTTP_200_OK,
             response_model=ResponseSuccess,
             summary='',
             description=''
             )
async def post_disable_db(db_name: str):
    try:
        response: ResponseSuccess = Handlers.databases_handler.post_change_db_enabled_state(db_name, False)
    except HTTPException as e:
        raise (e)
    except Exception as e:
        logger.exception(f'Changing state of DB to enabled=False failed due to: {e.__repr__()}')
        raise HTTPException(HTTP_500_INTERNAL_SERVER_ERROR, detail=e.__repr__())

    return response

enter image description here

RaamEE
  • 3,017
  • 4
  • 33
  • 53