1

I have an endpoint to update a given entity, and the response should be the updated entity. I hterefore tried the following, however, the redirect is another PUT request. How do I respond with a GET request?

$app->put('/foo/{id:[0-9]+}', function (Request $request, Response $response, $args) {
    $this->foo->update($args['id'], $request->getParsedBody());
    return $response->withRedirect("/foo/$args[id]");
});
Álvaro González
  • 142,137
  • 41
  • 261
  • 360
user1032531
  • 24,767
  • 68
  • 217
  • 387
  • Possible duplicate of [PHP Redirect to another page after form submit](https://stackoverflow.com/questions/17157685/php-redirect-to-another-page-after-form-submit) – Mike 'Pomax' Kamermans Aug 29 '19 at 16:27
  • @Mike'Pomax'Kamermans Form submission doesn't use `PUT`. – Barmar Aug 29 '19 at 16:29
  • No, but that's not exactly the important part in terms of achieving the redirect? – Mike 'Pomax' Kamermans Aug 29 '19 at 18:02
  • 301/302 **may** change the request to `GET` and 307 will guarantee no change. The http request method comes from the client side, so I am not sure how you can "respond" with a GET request. I think what you are trying to do is redirect and have `/foo/[id]` do the actual update instead of trying to pretend the response came from /foo. Remove the `$this->foo->update(...)` call and expose that endpoint instead. Now the `->withRedirect("/foo/$args[id]")` will do the update at the correct endpoint on the client side. – Alex Barker Aug 29 '19 at 18:58
  • @AlexBarker The entity is updated using the content supplied the requests body, and the JSON representation of the entity is returned to the client. To implement this, I wanted the `PUT /foo/[id]` request to redirect to a `GET /foo/[id]` request which provides this JSON representation of the entity. – user1032531 Aug 29 '19 at 21:09
  • Just call your model's `get()` to return the object! The redirect is to tell the client that the resource is located elsewhere. For example: `POST /foo` to create an object can return 201 Created with a `location: /foo/:id` where the client can find the object if they desire. You could do something similar with 202 Found for Put/Patch if you want. Please note, if you are providing a `Location` header, you should not be providing a response body. – Alex Barker Aug 29 '19 at 21:14
  • Don't quite understand why you sending a PUT request if you are expecting a json response. Why not use GET to begin with? – EternalHour Aug 30 '19 at 03:50
  • @AlexBarker Ah, I think I see my source of confusion. Unlike a standard HTML request, the redirect is not instructing the client to make another json request, but just providing the location for information only and the client may or may not request it based on its needs. One think I never understood is how the slim docs show `return $response->withRedirect('/new-url', 301)` for a response to a post request (http://www.slimframework.com/docs/v3/objects/response.html, http://www.slimframework.com/docs/v3/cookbook/action-domain-responder.html). Doesn't it need some unique identifier? – user1032531 Aug 30 '19 at 12:58
  • @EternalHour The primary purpose is to update the entity, and the response body is just to inform the body of the new updated state of the entity. – user1032531 Aug 30 '19 at 13:00

1 Answers1

2

You can use a 303 redirect:

The response to the request can be found under another URI using the GET method. When received in response to a POST (or PUT/DELETE), the client should presume that the server has received the data and should issue a new GET request to the given URI.

https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#303

$app->put('/foo/{id:[0-9]+}', function (Request $request, Response $response, $args) {
    $this->foo->update($args['id'], $request->getParsedBody());
    return $response->withStatus(303)->withRedirect("/foo/$args[id]");
});
Anonymous
  • 11,748
  • 6
  • 35
  • 57
  • Thanks Anonymous. One could also do `return $response->withRedirect("/foo/$args[id]", 303);` Turns out I was making a silly mistake. Client PUT to Server1, Server1 uses cURL to PUT to Server2, Server2 respond withRedirect(url), Server2 follows the request instead of responding to client. – user1032531 Aug 30 '19 at 14:15
  • No problem. That’s fine, the question may help someone else – Anonymous Aug 30 '19 at 16:08