www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - POST request with std.net.curl

reply bachmeier <no spam.net> writes:
I'm writing a D program that interacts with the Todoist API using 
std.net.curl. It's not a problem to do get requests to query 
tasks, but I cannot find a way to get post to work to create a 
new task.

This is a working bash script, where APIKEY is defined elsewhere 
and $1 and $2 are user input when running the script:

```
curl "https://api.todoist.com/rest/v1/tasks" -X POST --data 
"{"'"'"content"'"'": "'"'"$1"'"'", "'"'"project_id"'"'": $2}" -H 
"Content-Type: application/json" -H "Authorization: Bearer 
$APIKEY"
```

(For obvious reasons I'm not going to provide a working example.) 
How can I translate this into a post function call within D?

[Todoist API 
Reference](https://developer.todoist.com/rest/v1/?shell#create-a-new-task)
Jul 23 2021
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 7/23/21 11:11 AM, bachmeier wrote:
 I'm writing a D program that interacts with the Todoist API using 
 std.net.curl. It's not a problem to do get requests to query tasks, but 
 I cannot find a way to get post to work to create a new task.
 
 This is a working bash script, where APIKEY is defined elsewhere and $1 
 and $2 are user input when running the script:
 
 ```
 curl "https://api.todoist.com/rest/v1/tasks" -X POST --data 
 "{"'"'"content"'"'": "'"'"$1"'"'", "'"'"project_id"'"'": $2}" -H 
 "Content-Type: application/json" -H "Authorization: Bearer $APIKEY"
 ```
 
 (For obvious reasons I'm not going to provide a working example.) How 
 can I translate this into a post function call within D?
 
 [Todoist API 
 Reference](https://developer.todoist.com/rest/v1/?shell#create-a-new-task)
I haven't used it but isn't it the version of post that takes a dictionary here? https://dlang.org/phobos/std_net_curl.html#.post If the Authorization is the problem, I wonder whether addRequestHeader is the solution: https://dlang.org/phobos/std_net_curl.html#.HTTP.addRequestHeader Ali
Jul 23 2021
parent reply bachmeier <no spam.net> writes:
On Friday, 23 July 2021 at 19:59:33 UTC, Ali Çehreli wrote:
 On 7/23/21 11:11 AM, bachmeier wrote:
 I'm writing a D program that interacts with the Todoist API 
 using std.net.curl. It's not a problem to do get requests to 
 query tasks, but I cannot find a way to get post to work to 
 create a new task.
 
 This is a working bash script, where APIKEY is defined 
 elsewhere and $1 and $2 are user input when running the script:
 
 ```
 curl "https://api.todoist.com/rest/v1/tasks" -X POST --data 
 "{"'"'"content"'"'": "'"'"$1"'"'", "'"'"project_id"'"'": $2}" 
 -H "Content-Type: application/json" -H "Authorization: Bearer 
 $APIKEY"
 ```
 
 (For obvious reasons I'm not going to provide a working 
 example.) How can I translate this into a post function call 
 within D?
 
 [Todoist API 
 Reference](https://developer.todoist.com/rest/v1/?shell#create-a-new-task)
I haven't used it but isn't it the version of post that takes a dictionary here? https://dlang.org/phobos/std_net_curl.html#.post If the Authorization is the problem, I wonder whether addRequestHeader is the solution: https://dlang.org/phobos/std_net_curl.html#.HTTP.addRequestHeader Ali
Authorization is working - it's the same whether I'm doing a GET or POST request. The problem is passing the data. The main problem is that the documentation doesn't explain how to translate a `--data` option into a `post` call. I've tried everything I can think of, including what's shown in the documentation, but haven't found anything that works.
Jul 23 2021
parent reply frame <frame86 live.com> writes:
On Friday, 23 July 2021 at 21:25:01 UTC, bachmeier wrote:

 Authorization is working - it's the same whether I'm doing a 
 GET or POST request. The problem is passing the data. The main 
 problem is that the documentation doesn't explain how to 
 translate a `--data` option into a `post` call. I've tried 
 everything I can think of, including what's shown in the 
 documentation, but haven't found anything that works.
You just need to supply a JSON encoded string for the data - from an object like std.json.JSONValue via its toString() method for example.
Jul 23 2021
parent bachmeier <no spam.net> writes:
On Saturday, 24 July 2021 at 06:01:25 UTC, frame wrote:
 On Friday, 23 July 2021 at 21:25:01 UTC, bachmeier wrote:

 Authorization is working - it's the same whether I'm doing a 
 GET or POST request. The problem is passing the data. The main 
 problem is that the documentation doesn't explain how to 
 translate a `--data` option into a `post` call. I've tried 
 everything I can think of, including what's shown in the 
 documentation, but haven't found anything that works.
You just need to supply a JSON encoded string for the data - from an object like std.json.JSONValue via its toString() method for example.
I understand, and indeed, that's what's done by the working curl command I posted. I don't know how to translate that into a post request using std.net.curl. The natural thing would be to pass as the second argument the same string I'm sending as the `--data` option to curl, but that doesn't work. I've decided to give up on std.net.curl and use executeShell to capture the output from shell commands.
Jul 25 2021
prev sibling parent reply bachmeier <no spam.net> writes:
On Friday, 23 July 2021 at 18:11:51 UTC, bachmeier wrote:

[...]

After all this, it turned out the answer was a simple (but not 
obvious) typo in the header information. It would be nice to get 
more information than "HTTP request returned status code 400 ()". 
I don't know if that's possible, but command line curl provides 
better messages.
Jul 25 2021
parent reply frame <frame86 live.com> writes:
On Sunday, 25 July 2021 at 13:07:36 UTC, bachmeier wrote:
 On Friday, 23 July 2021 at 18:11:51 UTC, bachmeier wrote:

 [...]

 After all this, it turned out the answer was a simple (but not 
 obvious) typo in the header information. It would be nice to 
 get more information than "HTTP request returned status code 
 400 ()". I don't know if that's possible, but command line curl 
 provides better messages.
In doubt you can turn on the verbose() method on the HTTP object.
Jul 25 2021
parent reply bachmeier <no spam.net> writes:
On Sunday, 25 July 2021 at 15:44:14 UTC, frame wrote:
 On Sunday, 25 July 2021 at 13:07:36 UTC, bachmeier wrote:
 On Friday, 23 July 2021 at 18:11:51 UTC, bachmeier wrote:

 [...]

 After all this, it turned out the answer was a simple (but not 
 obvious) typo in the header information. It would be nice to 
 get more information than "HTTP request returned status code 
 400 ()". I don't know if that's possible, but command line 
 curl provides better messages.
In doubt you can turn on the verbose() method on the HTTP object.
That's a modest improvement (for the small number of people that find the option in the docs) but definitely not at the same level of information as the curl CLI. I created an issue requesting better output: <https://issues.dlang.org/show_bug.cgi?id=22142>
Jul 26 2021
parent reply frame <frame86 live.com> writes:
On Monday, 26 July 2021 at 14:13:53 UTC, bachmeier wrote:

 In doubt you can turn on the verbose() method on the HTTP 
 object.
That's a modest improvement (for the small number of people that find the option in the docs) but definitely not at the same level of information as the curl CLI. I created an issue requesting better output: <https://issues.dlang.org/show_bug.cgi?id=22142>
I see your intention but this is a bad example. Status 400 means "Bad request" because of a wrong header or wrong payload or any error in the request. "Empty content" wouldn't describe the actual error if you have sent data. In fact the client cannot know whats wrong. "Content-Type: Application/json" may be wrong from the sight of the server (which is NOT, they are case insensitive btw) but the protocol allows you to use whatever content-type you want and no client needs to know how to handle all. It's just wrong if your CLI tool interprets a status 400 as "Empty content" by arbitrary assumptions. All better the lib could do is to print the text for the status too and the raw payload sent by the server aka error description, if any.
Jul 26 2021
parent bachmeier <no spam.net> writes:
On Monday, 26 July 2021 at 19:53:05 UTC, frame wrote:

 All better the lib could do is to print the text for the status 
 too and the raw payload sent by the server aka error 
 description, if any.
That's what I'm proposing. Currently std.net.curl's post function doesn't report all the information sent by the server, while curl at the command line does.
Jul 27 2021