Вопрос или проблема
В следующем примере кода я пытаюсь использовать запрос GraphQL и мне нужно передать значение строки, которое я получаю из аргумента командной строки в запрос:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
"os"
)
func main() {
input := os.Args[1]
jsonData := map[string]string{
"query": `
mutation manager($input: managerinput!) {
manager(input: $input) {
name {
}
error {
...SystemError
}
}
}
`,
}
jsonValue, _ := json.Marshal(jsonData)
request, err := http.NewRequest("POST", "https://<GRAPHQL_API_HERE>", bytes.NewBuffer(jsonValue))
client := &http.Client{Timeout: time.Second * 10}
response, err := client.Do(request)
defer response.Body.Close()
if err != nil {
fmt.Printf("HTTP-запрос завершился неудачей с ошибкой %s\n", err)
}
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
}
Как мне передать значение input в блоке запроса? $input не работает, но я новичок и не могу найти способ передать значение переменной внутри многострочной строки блока “query”, который начинается и заканчивается символом `.
Вы можете использовать fmt.Sprintf аналогично тому, как вы уже используете fmt.Printf (я полагаю, вы все еще можете определить многострочную строку, начав/заключив ее в `).
Если вы рассматриваете более объектно-ориентированный способ работы с графовым сервером, попробуйте использовать метод, подобный https://github.com/hasura/go-graphql-client.
Ответ или решение
Для того чтобы передать значение переменной input
в строке запроса GraphQL, вам нужно использовать форматирование строк, так как в текущем примере вы используете многострочную строку, которая не поддерживает подстановку переменных напрямую.
Одним из способов решения этой проблемы является использование функции fmt.Sprintf
, чтобы динамически создавать строку запроса с подставленным значением переменной. Вот пример, как это можно сделать:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
"os"
)
func main() {
input := os.Args[1] // Получаем значение из аргументов командной строки
// Формируем строку запроса, подставляя значение input в нужное место
query := fmt.Sprintf(`
mutation manager($input: managerinput!) {
manager(input: %s) {
name {
}
error {
...SystemError
}
}
}
`, input)
jsonData := map[string]interface{}{
"query": query,
}
jsonValue, err := json.Marshal(jsonData)
if err != nil {
fmt.Printf("Ошибка при сериализации JSON: %s\n", err)
return
}
request, err := http.NewRequest("POST", "https://<GRAPHQL_API_HERE>", bytes.NewBuffer(jsonValue))
if err != nil {
fmt.Printf("Ошибка при создании запроса: %s\n", err)
return
}
request.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: time.Second * 10}
response, err := client.Do(request)
if err != nil {
fmt.Printf("HTTP-запрос не удался: %s\n", err)
return
}
defer response.Body.Close()
data, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Printf("Ошибка при чтении ответа: %s\n", err)
return
}
fmt.Println(string(data))
}
Комментарии к коду:
-
Форматирование строки
query
: Используемfmt.Sprintf
, чтобы подставить значениеinput
в запрос. Обратите внимание, что при передаче переменной вы можете столкнуться с проблемой формата данных, так как GraphQL ожидает, что данные будут представлены в формате JSON. Поэтому возможно придется сериализовать данные в JSON. -
Обработка ошибок: Не забывайте обрабатывать ошибки, связанные с сериализацией JSON и выполнением HTTP-запроса.
-
Заголовки запроса: Добавили заголовок
Content-Type
, устанавливающий тип контента наapplication/json
, что необходимо для корректной обработки запроса на сервере. -
Проверка аргументов: Следует добавлять проверку на количество аргументов командной строки, чтобы избежать паники в случае, если программа запущена без аргументов.
Такой подход обеспечит передачу переменной в многострочной строке запросов GraphQL. В качестве альтернативы для более сложных взаимодействий с GraphQL-сервером вы можете рассмотреть использование библиотек, таких как go-graphql-client
, что может упростить создание и выполнение запросов.