How to send HTTP POST requests using only Rebol3 - http

What is the simplest way of sending HTTP POST requests and getting response (in XML format for example) using only Rebol3?
Is there an equivalent of using read/custom in Rebol2, as it is done in this question?
How to send an HTTP post with a custom header using REBOL
And where should I be donwnloading my Rebol3 binaries from? I've not found a lot of documentation on that...

The documentation at on Ports: Synchronous and Asynchronous Operations shows how to use both GET and POST. To summarize:
The default behavior is to assume the post data should be considered as application/x-www-form-urlencoded. (If you want to encode a block of ordinary Rebol data into that format, see %altwebform.r)
result: write http://www.rebol.com/cgi-bin/updata.r data
If you need a custom header, then instead of passing a string you need to pass a block. Start it with the WORD! post followed by a block of Rebol-formatted key/value pairs, and then your data:
result: write http://www.rebol.com/cgi-bin/updata.r compose [
post [
Content-type: "text/x-rebol"
;-- other fields here
]
(data)
]
The result will be in binary! and can be converted to string! to parse out any XML or whatever.
where should I be downloading my Rebol3 binaries from?
You should download binaries from http://www.rebolsource.net/

Related

How to set the format of a reply to a REST service in BW6

I'm new to BW6 (v.6.3.1) and I'm playing around with it's REST features.
Currently I'm building a very simple echo service to figure out how it processes parameters etc.
One of the things I've noticed is that I can specify multiple Reply Client Formats, namely XML & JSON. But I can't find how I can specify what output to use in the actual reply.
Currently I've setup the following Resource Service Path:
/echo/{param}.{format}
I want to use the format parameter to drive the output I'll be getting. So
/echo/printme.xml
would result in
<messageBody>printme</messageBody> (or something to that extent)
And
/echo/printme.json
would result in
printme
I've tried several approaches, splitting the flow based on the contents of "format" but to no avail. If I have JSON checked as the Reply Client Format it will reply with JSON. Only if XML is the only Reply Client Format checked the reply will output XML. BW handles the rendering of either JSON or XML transparently.
So, how can I tell BW to output in either XML or JSON when both are selected as a Reply Client Format?
Edit:
Using the swagger UI I figured out how I can drive this behavior. By specifying the following header:
curl -X GET --header "Accept: application/xml" "http://localhost:8080/echo"
As per the documentation
Select the Invoke REST API pallette, you can choose the type(either request or response) as shown below:
If you click on it, there are three options JSON, XML and Custom. If you want to choose other than json and xml then choose Custom.
Custom(For RequestType) : Custom: to override the Content-Type value in the Input tab, select CUSTOM and provide the value in the Input tab.
Custom(For ResponseType): to override the Accept header value in the Input tab, select CUSTOM and provide the value in the Input tab.
Below is the Input tab where you can override when type is Custom:

What is the difference between PUT, POST and PATCH?

What is the difference between PUT, POST and PATCH methods in HTTP protocol?
Difference between PUT, POST, GET, DELETE and PATCH in HTTP Verbs:
The most commonly used HTTP verbs POST, GET, PUT, DELETE are similar to CRUD (Create, Read, Update and Delete) operations in database. We specify these HTTP verbs in the capital case. So, the below is the comparison between them.
Create - POST
Read - GET
Update - PUT
Delete - DELETE
PATCH: Submits a partial modification to a resource. If you only need to update one field for the resource, you may want to use the PATCH method.
Note:
Since POST, PUT, DELETE modifies the content, the tests with Fiddler for the below url just mimicks the updations. It doesn't delete or modify actually. We can just see the status codes to check whether insertions, updations, deletions occur.
URL: http://jsonplaceholder.typicode.com/posts/
GET:
GET is the simplest type of HTTP request method; the one that browsers use each time you click a link or type a URL into the address bar. It instructs the server to transmit the data identified by the URL to the client. Data should never be modified on the server side as a result of a GET request. In this sense, a GET request is read-only.
Checking with Fiddler or PostMan:
We can use Fiddler for checking the response. Open Fiddler and select the Compose tab.
Specify the verb and url as shown below and click Execute to check the response.
Verb: GET
url: http://jsonplaceholder.typicode.com/posts/
Response: You will get the response as:
"userId": 1, "id": 1, "title": "sunt aut...", "body": "quia et suscipit..."
In the “happy” (or non-error) path, GET returns a representation in XML or JSON and an HTTP response code of 200 (OK). In an error case, it most often returns a 404 (NOT FOUND) or 400 (BAD REQUEST).
2) POST:
The POST verb is mostly utilized to create new resources. In particular, it's used to create subordinate resources. That is, subordinate to some other (e.g. parent) resource.
On successful creation, return HTTP status 201, returning a Location header with a link to the newly-created resource with the 201 HTTP status.
Checking with Fiddler or PostMan:
We can use Fiddler for checking the response. Open Fiddler and select the Compose tab.
Specify the verb and url as shown below and click Execute to check the response.
Verb: POST
url: http://jsonplaceholder.typicode.com/posts/
Request Body:
data: {
title: 'foo',
body: 'bar',
userId: 1000,
Id : 1000
}
Response: You would receive the response code as 201.
If we want to check the inserted record with Id = 1000 change the verb to Get and use the same url and click Execute.
As said earlier, the above url only allows reads (GET), we cannot read the updated data in real.
3) PUT:
PUT is most-often utilized for update capabilities, PUT-ing to a known resource URI with the request body containing the newly-updated representation of the original resource.
Checking with Fiddler or PostMan:
We can use Fiddler for checking the response. Open Fiddler and select the Compose tab.
Specify the verb and url as shown below and click Execute to check the response.
Verb: PUT
url: http://jsonplaceholder.typicode.com/posts/1
Request Body:
data: {
title: 'foo',
body: 'bar',
userId: 1,
Id : 1
}
Response: On successful update it returns status 200 (or 204 if not returning any content in the body) from a PUT.
4) DELETE:
DELETE is pretty easy to understand. It is used to delete a resource identified by a URI.
On successful deletion, return HTTP status 200 (OK) along with a response body, perhaps the representation of the deleted item (often demands too much bandwidth), or a wrapped response (see Return Values below). Either that or return HTTP status 204 (NO CONTENT) with no response body. In other words, a 204 status with no body, or the JSEND-style response and HTTP status 200 are the recommended responses.
Checking with Fiddler or PostMan:
We can use Fiddler for checking the response. Open Fiddler and select the Compose tab.
Specify the verb and url as shown below and click Execute to check the response.
Verb: DELETE
url: http://jsonplaceholder.typicode.com/posts/1
Response: On successful deletion it returns HTTP status 200 (OK) along with a response body.
Example between PUT and PATCH
PUT
If I had to change my first name then send PUT request for Update:
{ "first": "Nazmul", "last": "hasan" }
So, here in order to update the first name we need to send all the parameters of the data again.
PATCH:
Patch request says that we would only send the data that we need to modify without modifying or effecting other parts of the data.
Ex: if we need to update only the first name, we pass only the first name.
Please refer the below links for more information:
https://jsonplaceholder.typicode.com/
https://github.com/typicode/jsonplaceholder#how-to
What is the main difference between PATCH and PUT request?
http://www.restapitutorial.com/lessons/httpmethods.html
The below definition is from the real world example.
Example Overview
For every client data, we are storing an identifier to find that client data and we will send back that identifier to the client for reference.
POST
If the client sends data without any identifier, then we will store the data and assign/generate a new identifier.
If the client again sends the same data without any identifier, then we will store the data and assign/generate a new identifier.
Note: Duplication is allowed here.
PUT
If the client sends data with an identifier, then we will check whether that identifier exists. If the identifier exists, we will update the resource with the data, else we will create a resource with the data and assign/generate a new identifier.
PATCH
If the client sends data with an identifier, then we will check whether that identifier exists. If the identifier exists, we will update the resource with the data, else we will throw an exception.
Note: On the PUT method, we are not throwing an exception if an identifier is not found. But in the PATCH method, we are throwing an exception if the identifier is not found.
Do let me know if you have any queries on the above.
Here is a simple description of all:
POST is always for creating a resource ( does not matter if it was duplicated )
PUT is for checking if resource exists then update, else create new resource
PATCH is always for updating a resource
PUT = replace the ENTIRE RESOURCE with the new representation provided
PATCH = replace parts of the source resource with the values provided AND|OR other parts of the resource are updated that you havent provided (timestamps) AND|OR updating the resource effects other resources (relationships)
https://laracasts.com/discuss/channels/general-discussion/whats-the-differences-between-put-and-patch?page=1
Simplest Explanation:
POST - Create NEW record
PUT - If the record exists, update else, create a new record
PATCH - update
GET - read
DELETE - delete
Think of it this way...
POST - create
PUT - replace
PATCH - update
GET - read
DELETE - delete
Request Types
create - POST
read - GET
create or update - PUT
delete - DELETE
update - PATCH
GET/PUT is idempotent
PATCH can be sometimes idempotent
What is idempotent -
It means if we fire the query multiple times it should not afftect the result of it.(same output.Suppose a cow is pregnant and if we breed it again then it cannot be pregnent multiple times)
get :-
simple get. Get the data from server and show it to user
{
id:1
name:parth
email:x#x.com
}
post :-
create new resource at Database. It means it adds new data. Its not idempotent.
put :-
Create new resource otherwise add to existing.
Idempotent because it will update the same resource everytime and output will be the same.
ex.
- initial data
{
id:1
name:parth
email:x#x.com
}
perform put-localhost/1
put email:ppp#ppp.com
{
id:1
email:ppp#ppp.com
}
patch
so now came patch request
PATCH can be sometimes idempotent
id:1
name:parth
email:x#x.com
}
patch name:w
{
id:1
name:w
email:x#x.com
}
HTTP Method
GET yes
POST no
PUT yes
PATCH no*
OPTIONS yes
HEAD yes
DELETE yes
Resources :
Idempotent -- What is Idempotency?
Main Difference Between PUT and PATCH Requests:
Suppose we have a resource that holds the first name and last name of a person.
If we want to change the first name then we send a put request for Update
{ "first": "Michael", "last": "Angelo" }
Here, although we are only changing the first name, with PUT request we have to send both parameters first and last.
In other words, it is mandatory to send all values again, the full payload.
When we send a PATCH request, however, we only send the data which we want to update. In other words, we only send the first name to update, no need to send the last name.
Quite logical the difference between PUT & PATCH w.r.t sending full & partial data for replacing/updating respectively. However, just couple of points as below
Sometimes POST is considered as for updates w.r.t PUT for create
Does HTTP mandates/checks for sending full vs partial data in PATCH? Otherwise, PATCH may be quite same as update as in PUT/POST
You may understand the restful HTTP methods as corresponding operations on the array in javascript (with index offset by 1).
See below examples:
Method
Url
Meaning
GET
/users
return users array
GET
/users/1
return users[1] object
POST
/users
users.push(body); return last id or index
PUT
/users
replace users array
PUT
/users/1
users[1] = body
PATCH
/users/1
users[1] = {...users[1], ...body }
DELETE
/users/1
delete users[1]
Reference to RFC: https://www.rfc-editor.org/rfc/rfc9110.html#name-method-definitions
POST - creates new object
PUT - updates old object or creates new one if not exist
PATCH - updates/modify old object. Primarly intended for for modificaiton.
There is few interpritation of RFC like mentioned before, but if you read carefully then you can notice that PUT and PATCH methods came after POST witch is common old fashion way to create native HTML Forms.
Therefore if you try to support all methods (like PATCH or DELETE), it can be suggested that the most approapreate way to use all methods is to stick to CRUD model:
Create - PUT
Read - GET
Update - PATCH
Delete - DELETE
Old HTML native way:
Read - GET
Create/Update/Delete - POST
Good Luck Coders! ;-)

Are PUT and POST requests required/expected to have a request body?

I'm writting a RESTful api, and at I'm thinking about the process of a user creating a key. I have the following possibilities:
GET request to /new/<keyname> - although it's very easy I think I won't use this, because I heard GET is for retrieving and/or listing information;
POST request to /<keyname> - This seemed to me easy and simple enough, but does not pass any data in the request body. Can I do it this way ? Is this weird ?
POST request to /keys passing in the request body "keyname=SomeKey" - Is this the correct way ?
I looked at this API from joyent and in all their PUT and POST requests they pass some data in the request body. Is this expected ? Is it really wrong not to require a request body in a PUT and POST request ?
I asked this question on the Http-WG. This was the most precise answer I got http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0276.html
In summary, POST does not require a body. I would expect the same justification can be applied to PUT.
RFC2616 is the base RFC for HTTP 1.1
In the most general form, an HTTP message is this (note the optional body):
generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
Reading further gives this:
9.5 POST
The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line. ...
and
9.6 PUT
The PUT method requests that the enclosed entity be stored under the
supplied Request-URI. ...
The fundamental difference between the POST and PUT requests is
reflected in the different meaning of the Request-URI. The URI in a
POST request identifies the resource that will handle the enclosed
entity. That resource might be a data-accepting process, a gateway to
some other protocol, or a separate entity that accepts annotations.
In contrast, the URI in a PUT request identifies the entity enclosed
with the request -- the user agent knows what URI is intended and the
server MUST NOT attempt to apply the request to some other resource.
Both POST and PUT include the phrase entity enclosed in the request.
Based on my reading, I believe that a body is desired (a non-normative description, I know) for both POST and PUT.
In the context of REST, POST is create and PUT is update. I can imagine creating an empty object (perhaps a placeholder for future information), but I don't imagine much use of an empty update.
It is not required. You can send a POST/PUT 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
Probably the best way is your third option: POST to /keys with keyname=SomeKey.
Here's why: You may wish to add another function to your API, for example create_new_user. It would then be difficult to tell the difference between a user trying to POST a key called create_new_user and a user trying to use the create_new_user function.
You are correct in saying that you should not be using GET to do this operation as the GET operation "SHOULD NOT have the significance of taking an action
other than retrieval." (RFC 2616).
To answer your question in one line. Yes it is expected to have Body/Content in body, but it is not required(Mandatory).
According to okHttp3 (an HTTP library for android): the following methods need a body: POST, PUT, PATCH, PROPPATCH (WebDAV) and REPORT (source). It even crashes if you try to do a request with the given methods without a body.

Is it considered bad practice to perform HTTP POST without entity body?

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?
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).
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.
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.
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?
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
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

Erlang: HTTP GET Parameters with Inets

This post indicates how to make a simple GET HTTP request with Erlang's Inets application.
Sometimes, URLs have GET parameters:
http://example.net/item?parameter1=12&parameter2=1431&parameter3=8765
Besides including the parameters in the URL itself, is there a way to create variables and then send them with the request?
Example appreciated.
ssl:start(),
application:start(inets),
httpc:request(post,
{"https://postman-echo.com/post",
[],"text/plain","parameter1=12&parameter2=1431&parameter3=8765"},
[], []).
You can use this example to use string interpolation to make a variable for parameter1..parameter3=8765.

Resources