Рубрики
Без рубрики

Сервер для связи сервера с использованием GraphQL

Сервер для связи сервера с использованием GraphQL. Помечено с Python, Go, GraphQl.

Разработка сервера Go API I была «документированной» пару недель назад.

С тех пор я добавил тесты (в основном функциональные), повторные детали и узнали немного больше о ходу.

API Server является владельцем собственной базы данных. Теперь, для того же приложения, мы создаем веб-приложение Frontend, которое для некоторых функций необходимо поговорить с сервером API и обменными данными.

Сервер API в настоящее время обнажает API для мобильных клиентов.

Моя первая мысль было добавить несколько конечных точек к этому API, но я мгновенно отвернул идею, потому что я определенно не хочу, чтобы мобильные клиенты могли получить доступ к этим конечным точкам аварии ;-).

Моя вторая идея состояла в том, чтобы создать отдельный API отдыха, на одном сервере и закрепите его по-другому. В основном разделяйте конечные точки для мобильных клиентов из те, которые используются этим веб-приложением и вызовите их через другой механизм аутентификации и вызовите его в день.

Веб-приложение очень много на этапе концепции и дизайна, и мы не уверены, как окончательное приложение будет полностью, поэтому мы не можем быть уверены, сколько у домена Go API будет необходимо или использовать веб-приложение.

Я решил использовать Graphql, который освобождает меня, более или менее, бремя проектирования другого API вообще. Он также предоставляет бесплатное самоанализ, которое идеально подходит на этом этапе.

Go graphql server.

Первым шагом было настроить сервер GraphQL в GO. После небольшого исследования я решил использовать gqlgen Отказ GQLGEN генерирует (!!) Сервер GraphQL с учетом определений типов и схема.

Пример схемы:

type Query {
    todos: [Todo!]!
    todo(todoID: ID!): Todo
}

type Mutation {
    createTodo(todo: TodoInput!): Todo
}

type Todo {
    todoID: ID!
    title: String!
    text: String!
}

input TodoInput {
    title: String!
    text: String!
}

Здесь, следуя стандарту Схема GraphQL Мы определяем два типа запросов (один для извлечения всех TODOS и один для определенного) и мутации (запрос на мутату), чтобы создать новый TODO. Мутация занимает Todoinput Что в основном модель ToDo минус автоматически сгенерированный ID.

Обычно gqlgen будет генерировать фактическую структуру/модель для использования в graphql. Поскольку у меня уже есть (тот, который использовался в API для отдыха), к счастью, я могу просто сказать генератору «импортировать» его из бизнес-логики. Более подробная информация в Документация GQLGEN Отказ

Следующий шаг – создать Резольверы , методы, вызываемые серверами GraphQL для возврата или создания данных, например:

package gql

type Resolver struct {
    DB *DataStore
}

func (r *Resolver) Query_todos(ctx context.Context) ([]models.Todo, error) {
    todos, err := r.DB.Todos()
    return todos, err
}

func (r *Resolver) Query_todo(ctx context.Context, todoID string) (*models.Todo, error) { 
    todo, err := r.DB.Todo(todoID)
    return todo, err
}

func (r *Resolver) Mutation_createTodo(ctx context.Context, todo models.Todo) (*models.Todo, error) {
    todo.TodoID = uuid.NewV4().String()
    err := r.DB.CreateTodo(&todo)
    return &todo, err
}

Первые называют бизнес-логикой для извлечения всех TODOS, второй извлекает один TODO, третий создает новый. Я на 100% повторное использование некоторых деловой логики общего с помощью API отдыха.

Последний шаг создает сам сервер:

gqlServer := &gql.Resolver{DB: db}
router.Handle("/gql-playground", handler.Playground("Todo", "/graphql"))
router.Handle("/graphql", handler.GraphQL(gql.MakeExecutableSchema(gqlServer)))

Эти три волшебные линии подвергают игровую площадку для проверки запросов и настоящий сервер GraphQL. Я не рекомендовал бы включить детскую площадку в производстве: D

Python Graphql клиент

Теперь, когда у нас есть сервер, нам нужен клиент в Python, чтобы увидеть, если все работает.

Я использую pygql , нравится:

from pygql import Client, gql
from pygql.transport.requests import RequestsHTTPTransport

# the URL is the url of the Go server
transport = RequestsHTTPTransport('http://localhost:8080/graphql', use_json=True)
# we tell Python to fetch the schema by itself!
client = Client(transport=transport, fetch_schema_from_transport=True)

# let's build a query to get all the ids and the titles of the todos in the db
query = gql("""
  query {
    todos {
      todoID
      title
    }
  }
""")

client.execute(query)

Это выход:

{
    'todos': [{
        'todoID': '403d9f8c-cdc3-4784-9582-aa0677681f4a',
        'title': 'I need to remember'
    }, {
        'todoID': '90b0edbc-75a8-4ae3-b345-11c520578f26',
        'title': 'There is something I need to remember'
    }]
}

Как вы можете видеть, что сервер GraphQL отправляется только то, что мы просили, вызывая правильные резользеры и выполняя все правильные преобразования.

Подчеркивая запрос с мутацией

query = gql("""
mutation createTodo {
  createTodo(todo: {
    title: "Another thing I need to remember", 
    text: "A very long text about everything I need to do"
  }) {
    todoID
    title
    text
  }
}
""")

Мы создаем новый TODO на сервере и вернуть свой идентификатор и остальные поля, если нам нужно.

Вывод

Таким образом, мы можем построить «постепенно» API между двумя серверами без «совершения» к определенной схеме. Изменение схемы является Super Easy на сервере, и клиент узнает, что ожидать. Клиент Python также поднимает исключения, если поле мы попросили, это не в схеме, без необходимости делать туристическую поездку на сервер, чтобы получить ошибку. Великое, что это клиент, который решает, какие данные для получения.

Пару соображений:

  • Нет auth между ними, что это не хорошая идея по понятным причинам. В настоящее время я решаю, как это сделать правильно. Я думал использовать Клиентские учетные данные Oauth 2 Flow (Крича на цифровой океан для Великого Учебного пособия OAUTH 2!). Таким образом, я могу контролировать всю жизнь токенов и кто получают доступ. Если у вас есть предложения, они более чем приветствуются.

  • Это не все радуги и единороги, Graphql является своего рода непрозрачным в журналах, и он не работает с HTTP-кешированием. Вы можете прочитать тщательное сравнение двух подходов здесь: https://philsturgeon.uk/api/2017/01/24/graphql-vs-rest-overview/

Оригинал: “https://dev.to/rhymes/server-to-server-communication-using-graphql-4b01”