-4

I found how to send a POST with URL parameters, or how to send a POST with a JSON body, but I do not know how to combine them together (a request with both a URL with parameters, and a JSON body).

The code below (which is not correct) shows the commbination I am looking for. I can use either bytes.NewBuffer(jsonStr) or strings.NewReader(parm.Encode()) but not both.

package main

import (
    "bytes"
    "net/http"
    "net/url"
    "strings"
)

func main() {
    var jsonStr = []byte(`{"title":"my request"}`)
    parm := url.Values{}
    parm.Add("token", "hello")
    req, err := http.NewRequest("POST", "https://postman-echo.com/post", bytes.NewBuffer(jsonStr), strings.NewReader(parm.Encode()))
    if err != nil {
        panic(err)
    }
    req.Header.Set("Content-Type", "application/json")
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

}

How to build a full POST call with all the components?

WoJ
  • 27,165
  • 48
  • 180
  • 345
  • I don't think you should be trying to send the URL parameters in the request body. As you say, you can't use both (because an HTTP request is meant to have a single body, the URL is separate). – Hymns For Disco May 29 '21 at 08:01
  • 2
    Those aren't URL parameters. URL parameters, by definition, are parameters _to the URL_. – Jonathan Hall May 29 '21 at 08:35
  • @Flimzy yes I know, I am starting with Go and trying to port what I know from Python where a single call gets both the parameters and the body. – WoJ May 29 '21 at 09:49
  • Curious. If you know that, I wonder why you said otherwise in your question. – Jonathan Hall May 29 '21 at 17:53
  • @Flimzy: can you please point where so that I can correct the misunderstanding? – WoJ May 29 '21 at 17:56
  • "I found how to send a POST with URL parameters" -- Yet you aren't sending any URL parameters. You're sending a body--which by definition is _not_ URL parameters. URl parameters are _part of the URL_, which you claim to know. Yet, you send them as the body?? – Jonathan Hall May 29 '21 at 18:01
  • @Flimzy: yes, my mistake was coming from looking at calls such as `req, err := http.NewRequest("POST", "https://...", strings.NewReader(parm.Encode()))`. In Python (requests) it is a single call that uses both the URL parameters and the body in one single call. I did not realize that in Go this was a two-step operation (new request, update of the URL parameters, and then the actual call (with the body)). As for "which I claim to know" - well I guess not having English as a first language does not help with the subtleties of the language. I should have mentioned that I know that **in general** – WoJ May 29 '21 at 18:09
  • You can do the same in Go, too: `http.NewRequest("POST", "https://.../?url_parameters_go_here_IN_THE_URL", someBody)` – Jonathan Hall May 29 '21 at 18:10
  • By passing `strings.NewReader(param.Encode())` as a body argument, it **is not URL parameters**. – Jonathan Hall May 29 '21 at 18:10
  • @Flimzy: I prefer however using the mechanisms of the language to ensure proper encoding etc., rather than manually chaining the parameters – WoJ May 29 '21 at 18:11
  • Nobody said you have to manually chain parameters. All I said is _they need to go in the URL_. How you build that URL is entirley up to you. Nothing you pass as body argument will ever be in the URL. – Jonathan Hall May 29 '21 at 18:11
  • 1
    @Flimzy *" ... is not URL parameters"* ahhhh, ok. I was reading a page where `parm` was used for both the body and the URL (in different examples) - this is where I got it wrong. – WoJ May 29 '21 at 18:14
  • I'm glad we finally cut through the confusion! – Jonathan Hall May 29 '21 at 18:15

1 Answers1

2

Use the only json as your request body, and apply the URL parameters like this:

req.URL.RawQuery = parm.Encode()

From Go doing a GET request and building the Querystring

Hymns For Disco
  • 7,530
  • 2
  • 17
  • 33