dart-lang / http

A composable API for making HTTP requests in Dart.
https://pub.dev/packages/http
BSD 3-Clause "New" or "Revised" License
1.03k stars 358 forks source link

Send a body on delete method #206

Closed lubritto closed 3 years ago

lubritto commented 6 years ago

The method http.delete just accept url and headers, can you put a body parameter ?

natebosch commented 6 years ago

A body isn't specifically disallowed by the spec but also has no specced semantics. I'm not sure if we'd add one or not.

What is the motivation?

Henge9 commented 6 years ago

I would like to have the body in the DELETE method because people don't read the standard, and the standard is vague.

OpenAPI Specification ver. 2 in swagger allows it. (At least in javascript and go)

Its probably wrong but it works.

rxwen commented 6 years ago

+1

ghost commented 6 years ago

For reference, RFC 2616 doesn't mention much in connection with DELETE, but RFC 7231 has the following to say:

A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.

So while setting body on a DELETE request isn't strictly forbidden in the spec, it is discouraged. Unless there is a really good use case for allowing it, it does not seem like a worthwhile investment to add it. The fact that other libraries allow it in itself is not a persuasive argument.

hacker1024 commented 5 years ago

Is it really our job to decide whether users are allowed to do things discouraged by the spec? A HTTP library should be able to do anything allowed by the spec, whether it's discouraged or not. This is a missing feature.

thosakwe commented 5 years ago

You can do this:

var rq = Request('DELETE', Uri.parse(...));
rq.bodyFields = {...};

var response = await client.send(rq).then(Response.fromStream);

It's not a "missing feature," IMO, because it's already supported. get, post, delete, etc. are just shorthand methods in the BaseClient class...

quetool commented 5 years ago

@thosakwe I am trying to implement your suggestion but it seems like I can not add headers parameters with that, is it possible?

quetool commented 5 years ago

I did it, I paste the code if it helps someone

(DELETE particular token from server)

http.Request rq = http.Request('DELETE', Uri.parse('${_getUrl()}/push.token'))
  ..headers.addAll({
    'Content-Type': 'application/x-www-form-urlencoded',
    'X-User-Id': _auth._id,
    'X-Auth-Token': _auth._token,
  });
rq.bodyFields = {
  'token': token,
};

http.StreamedResponse response = await http.Client().send(rq);
devmvk commented 5 years ago

Please add support for body parameter in http.delete method

thosakwe commented 5 years ago

I feel this would be trivial to send in a PR for.

On Sun, May 12, 2019 at 2:58 PM devmvk notifications@github.com wrote:

Please add support for body parameter in http.delete method

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/dart-lang/http/issues/206#issuecomment-491620101, or mute the thread https://github.com/notifications/unsubscribe-auth/ACMIUPF7L4MUFFSEAHACV3TPVBSEFANCNFSM4F2QRNPA .

--

Tobe Osakwe Student, B.S. Comp. Sci, Florida State University https://thosakwe.com

dfmiller commented 4 years ago

Use case: Deleting a resource does not necessarily mean it is actually being deleted. It may be being marked deleted in the database and may require a reason for the deletion.

DartMen commented 4 years ago

Ive also encountered badly designed API's which needs payloads in DELETE methods and had to implement some boilerplate to make this work.

Would love to see an optional overridable method to feed a payload.

danangponorogo commented 4 years ago

Hi all, I've just found simple code to get call back value after delete with RESTful endpoint, still can't go with http.delete, but it can do RESTful delete as expected with id parameter on body. thanks to @quetool for the inspiration. Here's the code:

`// Flutter code

void deleteData() async { http.Request rq = http.Request('DELETE', Uri.parse(widget.url)); rq.bodyFields = { 'id': widget.list[widget.index]['id'], }; await http.Client().send(rq).then((response) { response.stream.bytesToString().then((value) { print(value); // it will print: {"status":"Success"} }); Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext context) => Home(), )); }); }`

`// PHP RESTfull code

function index_delete() // Delete { $id = $this->delete('id'); $delete = $this->model->delete($id); if ($delete) { $this->response(array('status' => 'Success'), 201); } else { $this->response(array('status' => 'Failed', 304)); } }`

cv-irvan commented 2 years ago

I did it, I paste the code if it helps someone

(DELETE particular token from server)

http.Request rq = http.Request('DELETE', Uri.parse('${_getUrl()}/push.token'))
  ..headers.addAll({
    'Content-Type': 'application/x-www-form-urlencoded',
    'X-User-Id': _auth._id,
    'X-Auth-Token': _auth._token,
  });
rq.bodyFields = {
  'token': token,
};

http.StreamedResponse response = await http.Client().send(rq);

how to get the body from response?

thosakwe commented 2 years ago

@cv-irvan Look at the last line of my solution above. Basically, you use http.Response.fromStream() to convert a StreamedResponse into a Response. And then you can fetch the body or bodyBytes.