How to configure http request with "form" in elm - http

I just started learning elm this week so excuse me if the question is super basic.
So, I want to send a keyword (which is part of my Model, as shown in the forms example at https://elm-lang.org/examples/forms) as a "form" from my elm frontend to my backend. My cURL HTTP request looks like this:
curl -X 'POST' --form 'keyword=key' 0.0.0.0:5000/search
How would I transform that into an HTTP request written in elm, specifically the --form part? I read the HTTP section in the elm guide, but it doesn't mention anything about this.

--form corresponds to a multipart request, which you can use Http.multipartBody to construct. This is the equivalent of your example curl request.
Http.post
{ url = "http://0.0.0.0:5000/search"
, body =
Http.multipartBody
[ Http.stringPart "keyword" "key"
]
, expect = Http.expectString GotText
}
With a multipartBody you can also post files and blobs with filePart and bytesPart, respectively, in addition to simple key-value pairs as done here using stringPart

Related

How to execute ElasticSearch agg query from Apache Nifi using InvokeHTTP?

I want to execute the following query from Apache Nifi:
GET /myindex/_search
{
"size": 0,
"aggs": {
"range": {
"date_range": {
"field": "Datetime",
"ranges": [
{
"from": "2017-02-17T16:00:00Z||-1H/H",
"to": "2017-02-17T16:00:00Z||/H"
}
]
}
}
}
}
I want to get the value of doc_count.
I tried to use InvokeHTTP and directly pasted the above-defined query into the field HTTP Method. I also set Remote URL to http://localhost:9200. I connected InvokeHTTP with PutFile in order to save a response on the disk. The relationship is Response.
When I run InvokeHTTP, it does not give me any error. However, it neither outputs any result (FlowFile for Response). I am sure that the result is not an empty set, because I tested this query with curl.
What is wrong with my approach? Should I define HTTP Method in some different way?
For verbs like POST, PUT, and PATCH, you'd normally have the above JSON body as the content of a flow file and pass that to InvokeHttp, setting the correct verb and URL there. However the InvokeHttp documentation states that the message body will not be sent for a GET verb.
The good news is that the Elasticsearch REST API for the search endpoint supports both GET and POST. From their latest doc: "Both HTTP GET and HTTP POST can be used to execute search with body. Since not all clients support GET with body, POST is allowed as well."
I would set the content of a flow file to the above JSON body (perhaps using GenerateFlowFile or ReplaceText), then use POST as the verb.
There is a JsonQueryElasticsearch processor, which supports JSON elasticsearch queries.
Your query goes into the Query field.
The processor has hits and aggregations relations for you to process the result.

Fossil JSON API: How to create a wiki page?

I've been trying to create a wiki page, ufollowing the documentation of the Fossil JSON API. When I put the URL http://myrepo.top/json/wiki/create?name=test I get and answer similar to:
{"fossil":"81d7d3f43ebd4e77095cfbacee7ebc9ae043a014760cde56d437dbd8b6a37c92","timestamp":1496771043,"resultCode":"FOSSIL-3002","resultText":"'name' parameter is missing.","command":"wiki/create","procTimeUs":4000,"procTimeMs":4}
I don't know how the page name is supposed to be given in the URL. I was imagining that was similar to the way you query wiki pages, but seems that the API is expecting something different. Could someone show me the proper way of adding the page name to the Fossil JSON API URL?
Thanks,
In the Fossil mailing list Warren gave me an answer on how to proceed:
curl -H "Content-Type: application/json" \
-d '{"authToken": "nunyabinness", \
"payload": {"name": "foo", "content": "bar"} }' \
http://localhost:8080/json/wiki/create
and that gives me the proper wiki page.
Looking at the source code, it would seem you need to send the new wiki page name in the body of the POST request:
{ name: "test"
, content: "# Test\n\nThis is a test page."
, mimetype: "text/x-markdown"
}
If I read the code correctly, both name and content need to be specified in the JSON body, but the mimetype can be specified either as a GET parameter, or in the JSON body.
Disclaimer: I haven't tested this code, since I have no JSON-enabled instance of Fossil at hand.

How to send HTTP POST requests using only Rebol3

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/

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.

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