beast icon indicating copy to clipboard operation
beast copied to clipboard

add http-clienc-sync examples for post/json/file

Open schvarcz opened this issue 3 years ago • 19 comments

Hello everyone.

According discussed on the issue 301, having a http-client-sync-post example would be extremely useful to new users. It seems to be a very old request that is still on demand.

This PR aims to provide a few examples. According suggested and requested on the issue 301.

Please, let me know if you would prefer the files organised on another way. Particularly about the Jamfile. I haven't had the need to use that before.

Kind regards

schvarcz avatar Jan 20 '22 18:01 schvarcz

There's no such thing as "performing a HTTP JSON". It's just post. The JSON example only differs in two lines:

std::string payload = "var1=1&var2=2";
req.set(http::field::content_type, "application/x-www-form-urlencoded");

Became

std::string payload = "{\"m_list\":[1,2,3]}";
req.set(http::field::content_type, "application/json");

This will just make it really hard for users to see what exactly is required/different. I suggest merging the examples.

To a lesser extent the same goes for the _get flavoured copy of the client example: it's quite literally just the post example with s/post/get/ and the body removed.

All examples with a body are missing prepare_payload to DoTheRightThing(TM) regardless of HTTP/1.1 vs HTTP/1.0 in relation to the content-length. Setting headers to non-string values no longer does the implicit conversion.

The multipart upload seems nice, I've added a few review comments there. I've rebased the PR branch on latest develop and incorporated the changes outlined in the review comments, except the merging of get/post-json/post-form examples. I'm open to suggestions on how to approach that.

sehe avatar Jun 07 '22 00:06 sehe

An automated preview of the documentation is available at https://2381.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/index.html

cppalliance-bot avatar Jun 07 '22 01:06 cppalliance-bot

An automated preview of the documentation is available at https://2381.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/index.html

cppalliance-bot avatar Jun 07 '22 01:06 cppalliance-bot

The Examples page in the docs needs to be updated: https://2381.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/beast/examples.html#beast.examples.clients

vinniefalco avatar Jun 08 '22 22:06 vinniefalco

We still need to preserve the file "http_client_sync.cpp" (this pull request renames it to "http_client_sync_get.cpp"). Otherwise anyone whose web page or email links to the file will break.

vinniefalco avatar Jun 08 '22 22:06 vinniefalco

The Examples page in the docs needs to be updated: https://2381.beastdocs.prtest.cppalliance.org/libs/beast/doc/html/beast/examples.html#beast.examples.clients

I tried to sollicit opinion on how to better organize the examples instead (I mentioned it as the reason why I did not add the other examples).

My current best plan is to introduce another defaulted CLI option (ugh) like "get", "post-formdata", "post-json" or "post-multipart". Alternative names: "get", "form", "json", "upload".

I guess the CLI interface - as a proper interface - is horrible, but the point is not to provide real-life CLI interface. What matters is that we can show several kinds of requests in the space of one example, highlighting the minimal set of differences, instead of duplicating the entire "bulky" example, leaving it to visitors to figure out the difference.

We still need to preserve the file "http_client_sync.cpp" (this pull request renames it to "http_client_sync_get.cpp"). Otherwise anyone whose web page or email links to the file will break.

Keeping in mind the wish to have permanent links, I suggest to keep "get" it's own example, as currently, and just provide a _post flavoured example containing the other three just listed.

sehe avatar Jun 08 '22 23:06 sehe

Yeah if you want to reorganize the examples to preserve the existing GET and filename, and then add a larger single example that demonstrates various types of client requests using different command line options, that sounds good.

vinniefalco avatar Jun 09 '22 00:06 vinniefalco

Yeah if you want to reorganize the examples to preserve the existing GET and filename, and then add a larger single example that demonstrates various types of client requests using different command line options, that sounds good.

Did that. Adding one or two questions in the code

sehe avatar Jun 09 '22 01:06 sehe

  • [ ] add examples to documentation
  • [ ] port to other example flavours? (I'm thinking just async? Not much use in also showing ssl or coro I think)

sehe avatar Jun 09 '22 02:06 sehe

Went ahead and added a json_body example with an example program that exercises it against httpbin.org/post

   example/json-body/http_client_json_body.cpp
   example/json-body/json_body.hpp

TODO:

  • [x] parse_options
  • [x] non-sized body writing using chunked encoding
  • [ ] link documentation

Note also the existing tasks in https://github.com/boostorg/beast/pull/2381#issuecomment-1150598250

@vinniefalco Perhaps it is more consistent to leave the entire http/client/*/ example tree as-is and put all the new examples of this PR under example/advanced/client/.

sehe avatar Jun 16 '22 00:06 sehe

I'm not particularly concerned about "multi-root JSON bodies" as that is not standard JSON. I assume you mean more than one JSON in a body? There's no spec for that, its outside the scope of JSON.

vinniefalco avatar Jun 16 '22 00:06 vinniefalco

parse_options are going to be a problem because Beast does not provide a clean way to customize the body read or write operation. We should choose sensible defaults and call it a day.

vinniefalco avatar Jun 16 '22 00:06 vinniefalco

reference value_type?

No idea what this is

non-sized body writing using chunked encoding

All JSON bodies should use chunked, because if you are going to measure the serialized size then you might as well just use a string body.

vinniefalco avatar Jun 16 '22 00:06 vinniefalco

reference value_type?

No idea what this is

Basically std::reference_wrapper<json::value /*const*/> instead of copying the value just in order to serialize it. That seems... dumb. (At least on the receiving side there's always the option to std::move(res.body()))

sehe avatar Jun 16 '22 00:06 sehe

non-sized body writing using chunked encoding

All JSON bodies should use chunked, because if you are going to measure the serialized size then you might as well just use a string body.

That was actually my option B. Somehow I failed to reach the realization that it's not even worth implementing the non-chunked version as it quite literally is message<..., string_body> msg(verb, target, 11, serialize(jv)) indeed. That should have clued me in to start out with option B :derp:

sehe avatar Jun 16 '22 00:06 sehe

Shoild this be combined with #2511 ?

klemens-morgenstern avatar Sep 24 '22 04:09 klemens-morgenstern

Closing this pull request as:

  • The json_body example has already been added in https://github.com/boostorg/beast/pull/2511.
  • The http_client_sync_post example is too complex to be considered a suitable example.

ashtum avatar Dec 27 '23 15:12 ashtum