HTTP-запрос POST с телом Go - PullRequest
       29

HTTP-запрос POST с телом Go

0 голосов
/ 28 сентября 2019

Я хочу создать HTTP-запрос POST с телом с использованием библиотеки Go net/http.

Функция, которую я использую для создания http-запроса, следующая: docs

http.NewRequest(method string, url string, body io.Reader)

Я предложил 2 решения, но я пытаюсь понять, какое из них более идиоматично и расширяемо для поддержки различных конфигураций тела.

Solution #1

bytesObj := []byte(`{"key":"value"}`)
body := bytes.NewBuffer(bytesObj)

Solution #2

bodyMap := map[string]string{"key":"value"}
bodyBytes, _ := json.Marshal(bodyMap)
body := bytes.NewBuffer(bodyBytes)

В идеале я перенесу код в вспомогательную функцию таким образом, чтобы я мог настроить конструкцию тела.Вспомогательная функция будет выглядеть примерно так:

func constructBody(someArgument) io.Reader {
  return bodyHere
}

Ответы [ 2 ]

0 голосов
/ 29 сентября 2019

Чтобы сделать его более пригодным для повторного использования, вы можете создать jsonReaderFactory, который занимает всего несколько строк кода:

func jsonReaderFactory(in interface{}) (io.Reader, error) {
    buf := bytes.NewBuffer(nil)
    enc := json.NewEncoder(buf)
    err := enc.Encode(in)
    if err != nil {
        return nil, fmt.Errorf("creating reader: error encoding data: %s", err)
    }
    return buf, nil
}

Пример на детской площадке

0 голосов
/ 28 сентября 2019

Если тело уже является строкой, параметры # 1 мне более привлекательны.

Если вы работаете только с ключом -> значение только со строкой, вариант № 2 лучше.Но это станет громоздким, когда вы вложите struct

Но в большинстве случаев, по моему опыту, мы имеем дело со struct.Мне нравится делать структуру ближе к тому, где произошел http-вызов.

func main() {
    ctx := context.Background()

    body := struct {
        Key string `json:"key"`
    }{
        Key: "value",
    }

    out, err := json.Marshal(body)
    if err != nil {
        log.Fatal(err)
    }


    req, err := http.NewRequest("POST", "http://example.com", bytes.NewBuffer(out))
    if err != nil {
        log.Fatal(err)
    }

    req = req.WithContext(ctx)

    http.DefaultClient.Do(req)
}

И если структура используется в нескольких местах, вы можете сделать структуру уровня пакета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...