GraphQL Mesh: Migrando API REST sem esquema para GraphQL sem escrever nenhum código
Tags: ptbr, webdev, graphql, javascript
Published: 2020-09-27 20:56:14

GraphQL foi originalmente criado para fornecer facilmente uma API poderosa em cima do código existente. A abordagem atual que as pessoas estão usando ao migrar de API REST para o GraphQL é criar um novo esquema e usar o GraphQL como um proxy. Isso traz muitos benefícios, porque nos dá a oportunidade de repensar a API e melhorá-la, sem alterar os serviços por baixo dela.

Vamos primeiro começar observando essa abordagem:

## Implementando um back-end de proxy GraphQL

Digamos que você tenha um endereço `/user` que faz todas as operações CRUD para a entidade `User`, com diferentes métodos HTTP, e você precisaria de um esquema GraphQL como abaixo:

```graphql
type Query {
  user(id: ID): User
}

type Mutation {
  createUser(input: UserInput): User
  updateUser(id: ID, input: UserInput): User
  deleteUser(id: ID): ID
}

type User {
  id: ID
  name: String
  age: Int
}

input UserInput {
  name: String
  age: Int
}
```

E você também precisaria de uma lógica de negócios para atuar como proxy das solicitações GraphQL para a API REST usando resolvedores GraphQL como abaixo;

```js
module.exports = {
   Query: {
      user: (root, args) => fetch('https://myrest.com/user/' + args.id)
      .then(res => res.json())
   },
  Mutation: {
     createUser: (root, args) => fetch('https://myrest.com/user', {
       method: 'PUT',
       body: JSON.stringify(args.input)
      }).then(res => res.json()),
    updateUser:  (root, args) => fetch('https://myrest.com/user' + args.id, {
       method: 'POST',
       body: JSON.stringify(args.input)
    }).then(res => res.json()),
    deleteUser:  (root, args) => fetch('https://myrest.com/user' + args.id, {
       method: 'DELETE'
    }).then(res => res.json()),
};
```

Este exemplo assume que você tem um endereço `/user/:id` que obtém uma entidade `User` com `HTTP GET`, exclui o usuário com `HTTP DELETE`e atualiza um `User` com o id e payload fornecido. Além disso, o endereço `/user` cria um novo `User` com o payload fornecido.

Mas essa implementação será difícil de manter quando a API REST for atualizada e se tornar maior.

## Usando GraphQL Mesh ao invés código

GraphQL Mesh é uma ferramenta que lida com várias fontes de dados não GraphQL e gera um esquema GraphQL executável sobre elas com um arquivo de configuração simples. [Você pode verificar o artigo de lançamento para saber mais](https://the-guild.dev/blog/graphql-mesh).

Além de ter manipuladores que cuidam automaticamente de fontes com esquema como - OpenAPI / Swagger, gRPC, SOAP e outros, ele também tem manipuladores de esquema JSON que gera um esquema GraphQL com base nos arquivos de esquema JSON fornecidos. Esse manipulador também pode gerar o esquema JSON no tempo de execução com base no payload de solicitação e nos dados de resposta.

Primeiro você precisa criar um projeto, vamos usar `yarn` em um diretório vazio:

```bash
yarn init
```

Depois disso, precisamos instalar algumas dependências do GraphQL Mesh:

```bash
yarn add @graphql-mesh/cli @graphql-mesh/json-schema graphql
```

Crie um `.meshrc.yml` que é um arquivo de configuração para GraphQL Mesh em nosso novo projeto:

```yml
sources:
  - name: MyRest
    handler:
      jsonSchema:
        baseUrl: https://myrest.com/
        operations:
          - type: Query
            field: user
            path: /user/{args.id}
            method: GET
            responseSample: ./getUserResponse.json
          - type: Mutation
            field: createUser
            path: /user
            method: POST
            requestSample: ./createUserRequest.json
            responseSample: ./createUserResponse.json
          - type: Mutation
            field: updateUser
            path: /user/{args.id}
            method: PUT
            requestSample: ./updateUserRequest.json
            responseSample: ./updateUserResponse.json
          - type: Mutation
            field: deleteUser
            path: /user/{args.id}
            method: DELETE
            responseSample: ./deleteUserResponse.json
```

Como você pode ver na configuração, definimos nossos endereços sem uma única linha de código. Depois de criar este arquivo de configuração. Precisamos obter arquivos de solicitação e resposta de amostra, podemos fazer isso chamando esses endereços localmente.

Com um único comando, nosso novo servidor GraphQL está pronto para uso:

```bash
yarn mesh serve
```
## Não é só um gateway, mas também, uma SDK totalmente segura

GraphQL Mesh é capaz de gerar um SDK com tipagem segura a partir da API GraphQL gerada porque o esquema GraphQL gerado é localmente. `GraphQLSchema` podem ser executados sem um servidor HTTP.

Isso significa que você pode usar o GraphQL Mesh dentro de seus serviços ou clientes existentes, [como um SDK](https://graphql-mesh.com/docs/recipes/as-sdk) , apenas como uma dependência simples, sem adicionar outro componente em sua arquitetura.

---

# Créditos

- [Migrating from Schemaless REST API to GraphQL without writing any code](https://the-guild.dev/blog/migrating-from-rest), escrito originalmente por [Arda Tanrıkulu](https://twitter.com/ardatanrikulu).