Как создать сервер API GraphQL с помощью Go (Golang)

  • 30 октября, 13:45
  • 6437
  • 0

В этой статье пример того, как создать GraphQL с использованием graphql-go и реализации GraphQL для Go/Golang.

Есть несколько интересных фреймворков, с которых вы можете начать при создании API-интерфейсов GraphQL с помощью Go. Вот некоторые из веб-сайта GraphQL :

  1. graphql-go : реализация GraphQL для Go/Golang.
  2. GQLGen - Go : генерирует основанную библиотеку GraphGL-сервера.
  3. graphql-relay-go : библиотека Go / Golang, помогающая создать сервер graphql-go с поддержкой response-relay.
  4. machinebox / graphql :  низкоуровневый HTTP-клиент для GraphQL.
  5. samsarahq / thunder : реализация GraphQL с простым построением схемы, оперативными запросами и пакетированием.

В этом примере мы будем использовать graphql-go, первый в списке. 

Ниже наша основная функция. В 3 строке мы создаем обработчик GraphiQL. Он включит GraphiQL для нашего сервера API, поэтому он не должен запускаться отдельно. GraphiQL - это браузерный инструмент для изучения API-интерфейсов GraphQL. Позже, когда мы закончим с кодом, мы сможем увидеть, как выглядит GraphiQL.

Поскольку мы хотели, чтобы наш сервер принимал запросы с использованием http, мы создали сервер в строке 10, работающий в порту 3000, с использованием стандартного пакета http. Нам также нужно обрабатывать запросы GraphQL, поэтому мы создали для него обработчик gqlHandler.

func main() {

  graphiqlHandler, err := graphiql.NewGraphiqlHandler("/graphql")
  if err != nil {
    panic(err)
  }

  http.Handle("/graphql", gqlHandler())
  http.Handle("/graphiql", graphiqlHandler)
  http.ListenAndServe(":3000", nil)

}

Ниже приведен код обработчика. В этой функции мы получаем запрос и декодируем его в json. Если при синтаксическом анализе json произошла ошибка, мы возвращаем HTTP-ошибку 400.

После этого функция processQuery () вызывается передачей в запросе.

func gqlHandler() http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    if r.Body == nil {
      http.Error(w, "No query data", 400)
      return
    }

    var rBody reqBody
    err := json.NewDecoder(r.Body).Decode(&rBody)
    if err != nil {
      http.Error(w, "Error parsing JSON request body", 400)
    }

    fmt.Fprintf(w, "%s", processQuery(rBody.Query))

  })
}

Вот как выглядит наша функция Query (). Мы извлекаем данные из файла json на данный момент, используя функцию dataFromJSON (), но в идеале это должен быть запрос к базе данных. После получения данных, которые мы будем использовать, мы вызываем gqlSchema (jobsData), который создает схему GraphQL из наших данных. jobsData - это фрагмент структур Job, содержащий данные из нашего файла json.

func processQuery(query string) (result string) {

  jobsData := dataFromJSON()

  params := graphql.Params{Schema: gqlSchema(jobsData), RequestString: query}
  r := graphql.Do(params)
  if len(r.Errors) > 0 {
    fmt.Printf("failed to execute graphql operation, errors: %+v", r.Errors)
  }
  rJSON, _ := json.Marshal(r)

  return fmt.Sprintf("%s", rJSON)

}

Волшебство GraphQL происходит в функции gqlSchema (jobsData). В этом примере у нас есть поддержка 2 запросов, / jobs и jobs / {id}

  1. / jobs - возвращает все задания (строка 3)
  2. / jobs / {id} - поддерживает идентификатор одного аргумента и возвращает одно задание, отфильтрованное по идентификатору (строка 10)

Resolvers для обеих функций находятся в строках 6 и 18. Resolvers отвечают за возврат данных для запроса.

func gqlSchema(jobsData []Job) graphql.Schema {
  fields := graphql.Fields{
    "jobs": &graphql.Field{
      Type: graphql.NewList(jobType),
      Description: "All Jobs",
      Resolve: func(params graphql.ResolveParams) (interface{}, error) {
        return jobsData, nil
      },
    },
    "job": &graphql.Field{
      Type: jobType,
      Description: "Get Jobs by ID",
      Args: graphql.FieldConfigArgument{
        "id": &graphql.ArgumentConfig{
          Type: graphql.Int,
        },
      },
      Resolve: func(params graphql.ResolveParams) (interface{}, error) {
        id, success := params.Args["id"].(int)
        if success {
          for _, job := range jobsData {
            if int(job.ID) == id {
              return job, nil
            }
          }
        }
        return nil, nil
      },
    },
  }
  rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
  schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
  schema, err := graphql.NewSchema(schemaConfig)
  if err != nil {
    fmt.Printf("failed to create new schema, error: %v", err)
  }

  return schema

}

Запустите сервер API GraphQL

git clone https://github.com/donvito/go-graphql-server-example.git
cd go-graphql-server-example/src/cmd/server/
go run main.go

Доступ к GraphiQL после запуска сервера

Теперь мы создали GraphQL API с помощью Go.

Полный исходный код доступен в репозитории github.

https://github.com/donvito/go-graphql-server-example

Рекомендации

https://github.com/graphql-go/graphql
https://github.com/friendsofgo/graphiql
https://graphql.org/code/#go 

Надеюсь, что это поможет любому, кто начинает с Go и GraphQL!


0 комментариев
Сортировка:
Добавить комментарий

IT Новости

Смотреть все