O segundo de três artigos focados na criação de React Fullstack e GraphQL com o Express e o Couchbase Server.
- Configuração de um servidor NoSQL Couchbase (Parte 1)
- Criação de uma API Express-GraphQL (Parte 2)
- Criar um cliente Apollo GraphQL em React (Parte 3)
- Código-fonte final
GraphQL com o Express
Se não estiver familiarizado com o GraphQL, reserve alguns minutos para se atualizar usando a documentação do GraphQL. As páginas a seguir devem ser um bom começo:
Pré-requisitos
Criar estrutura de projeto
Precisamos criar um diretório em seu computador para nosso projeto, que chamaremos de raiva com base de toque:
|
1 |
mkdir raiva-com-couchbase && cd $_ |
mkdir criará um novo diretório usando a string raiva com base de toque para o nome da pasta, o bash armazena essa string em uma variável que podemos usar imediatamente chamada $_.
alteramos os diretórios usando $_ garantindo que não digitemos incorretamente o diretório no comando concatenado (é a mágica do bash).
Agora vamos criar um .gitignore na raiz do nosso projeto.
|
1 |
toque .gitignore && eco "/node_modules/*" >> .gitignore |
toque gerará um .gitignore ignorando todos os arquivos módulos_nó e subdiretórios em nosso projeto. Isso é importante porque, como parte do nosso projeto de demonstração fullstack React e GraphQL, rastrearemos as alterações do git a partir da raiz raiva com base de toque mas teremos diretórios de servidor e cliente com seus próprios package.json e módulos_nó diretório.
eco adicionará o node_modules/ texto dentro do .gitignore isso servirá para ignorar todos os arquivos módulos_nó na raiz e em todos os subdiretórios.
Criando nosso Express Server
Agora, criaremos o diretório para armazenar nosso servidor Express e usaremos o npm para gerenciar seus pacotes.
|
1 |
mkdir couchbase-gql-servidor && cd $_ && npm inicial -y |
mkdir criará uma nova pasta dentro da raiz do projeto especificamente para nosso servidor usando a string servidor couchbase-gql para o nome, esse é o diretório do projeto do servidor.
mudamos de diretório e usamos o $_ (mais mágica) e, em seguida, inicializamos um npm projeto usando npm init -y aceitando os valores padrão com a opção -y bandeira.
Instalar as dependências do Express Server
|
1 |
npm instalar graphql expresso expresso-graphql couchbase && npm instalar nodemônio -D && código . |
Após a conclusão da instalação, precisamos abrir o projeto com o editor de nossa preferência. Eu prefiro o VS Code.
Criar nosso servidor GraphQL
|
1 |
toque servidor.js .gitignore && eco "/node_modules/*" >> .gitignore |
Exigir express/express-graphql/graphql em nossa servidor.js file:
|
1 2 3 4 5 |
const expresso = exigir("expresso) const { graphqlHTTP } = exigir('express-graphql') const { buildSchema } = exigir('graphql') const couchbase = exigir('couchbase') |
As três primeiras importações são necessárias para o nosso servidor GraphQL e a última importação é necessária para a conexão e a consulta ao nosso servidor Couchbase.
Inicializar o Express e conectar-se ao nosso Bucket
Adicione o seguinte código:
|
1 2 3 4 5 6 |
const aplicativo = expresso() const agrupamento = novo couchbase.Aglomerado('couchbase://localhost', { nome de usuário: "Administrador, senha: 'senha' }) const balde = agrupamento.balde('amostra de viagem') var coleção = balde.defaultCollection(); |
Acima, estamos nos conectando ao nosso cluster do Couchbase Server, autenticando com o usuário que configuramos e abrindo nosso amostra de viagem balde. Nunca use nomes de usuário e senhas padrão em aplicativos de produção.
Criar nosso esquema GraphQL
A adição do código abaixo definirá dois pontos de extremidade que permitirão que o nosso servidor GraphQL acesse e recupere dados dos nossos documentos dentro do nosso bucket do Couchbase Server.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
const esquema = buildSchema(` tipo Companhia aérea { id: Int, indicativo: Cordas, país: Cordas, iata: Cordas, icao: Cordas, nome: Cordas, tipo: Cordas } entrada AirlineInput { indicativo: Cordas, país: Cordas, iata: Cordas, icao: Cordas, nome: Cordas, tipo: Cordas } tipo Consulta { companhias aéreasUK: [Companhia aérea], companhia aéreaByKey(id: Int!): Companhia aérea companhias aéreasByRegion(região: Cordas!): [Companhia aérea] } tipo Mutação { updateAirline(id: Int!, entrada: AirlineInput): Companhia aérea } |
O Consulta especifica qual tipo de Consultas GraphQL clientes podem executar em seu próprio gráfico de dados.
Temos dois pontos de extremidade definidos por isso Consulta. Um chamado "airlinesUK" e o outro "airlineByKey". Em nosso aplicativo React, usaremos apenas o endpoint "airlinesUK". Criei o endpoint "airlineByKey" simplesmente para mostrar um exemplo de recuperação de um único documento do Couchbase por chave. Essa operação não usa a linguagem de consulta N1QL e, portanto, não tem nenhuma sobrecarga adicional. Entender quando e onde usar cada uma delas é importante do ponto de vista da criação da API; não queremos usar uma consulta N1QL para retornar um único documento que podemos obter por chave.
Em nosso código GraphQL, temos um objeto do tipo Companhia aérea. Esse objeto modela a estrutura do documento encontrada em nosso Couchbase amostra de viagem onde o tipo é "companhia aérea".
Em seguida, temos um endpoint chamado "companhias aéreasUK". Observe que o valor de retorno desse ponto final é uma matriz de Airline: [Companhia aérea].. Isso significa que receberemos uma lista de companhias aéreas de volta.
Também temos "companhia aéreaByKey", onde buscaremos um único Companhia aérea.
Se você se lembra das imagens do Bucket acima, cada documento é definido por uma chave em um formato como companhia aérea_1234 onde 1234 é o id da companhia aérea.

Manteremos isso id em mente ao usar o SDK do NodeJS para buscar nossos companhia aéreaByKey usando um simples bucket.get() método.
Criar nossa implementação de resolvedor para cada endpoint
Agora que definimos duas consultas em nossa API GraphQL-Express usando nosso esquema precisamos de uma implementação em JavaScript para recuperar os dados.
Nosso aplicativo React que criaremos precisará apenas do N1QL consulta nomeada companhias aéreasUK.
Mas eu queria mostrar a você como fazer consultas sem N1QL usando a API do SDK do NodeJS usando apenas uma chave ou estendendo-a para usar uma região (EUA/Reino Unido, etc.), que é o companhia aéreaByKey e companhia aérea por região implementação.
Adicione o seguinte código ao nosso servidor.js para nossas consultas N1QL:
(Em seu código JS, certifique-se de escapar dos sinais de barra invertida com barras invertidas)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Definir consultas N1QL const companhias aéreasUkQuery = ` SELECIONAR companhia aérea.* DE `viagens-amostra` AS companhia aérea ONDE companhia aérea.tipo = "companhia aérea E companhia aérea.país = "Reino Unido ` const airlinesByRegionQuery = ` SELECIONAR companhia aérea.* DE `viagens-amostra` AS companhia aérea ONDE companhia aérea.tipo = "companhia aérea E companhia aérea.país = $REGIÃO ` |
Adicione o seguinte código ao nosso servidor.js para nossos resolvedores GraphQL:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
const raiz = { companhias aéreasUK: assíncrono () => { const resultado = aguardar agrupamento.consulta(companhias aéreasUkQuery) retorno resultado.linhas }, /* consulta getAirlinesUK { airlinesUK { id nome indicativo país iata icao } } */ companhias aéreasByRegion: assíncrono ({região}) => { const opções = { parâmetros: { REGIÃO: região } } const resultado = aguardar agrupamento.consulta(airlinesByRegionQuery, opções) retorno resultado.linhas }, /* consulta getAirlinesByRegion($region: String!) { airlinesByRegion(region:$region) { id nome indicativo país iata icao } } { "region": "{{country}}" } */ companhia aéreaByKey: assíncrono ({id}) => { const resultado = aguardar coleção.obter(`companhia aérea${id}`) retorno resultado.valor }, /* consulta getAirlineByKey($id: Int!) { airlineByKey(id:$id) { id nome indicativo país iata icao } } { "id": {{id}} } */ updateAirline: assíncrono ({id, entrada}) => { const resultado = aguardar coleção.obter(`companhia aérea${id}`) const novoDocumento = { ...resultado.conteúdo, indicativo: entrada.indicativo ? entrada.indicativo : resultado.valor.indicativo, país: entrada.país ? entrada.país : resultado.valor.país, iata: entrada.iata ? entrada.iata : resultado.valor.iata, icao: entrada.icao ? entrada.icao : resultado.valor.icao, nome: entrada.nome ? entrada.nome : resultado.valor.nome, }; console.registro(novoDocumento) aguardar coleção.upsert(`companhia aérea${id}`, novoDocumento) retorno novoDocumento } /* mutation updateExistingAirline($id:Int!, $input:AirlineInput) { updateAirline(id:$id, input:$input){ indicativo país iata } } { "id": 112, "input": { "Indicativo": "FLYSTAR", "country": "United Kingdom" (Reino Unido) } } */ } |
Observação: Na instrução N1QL acima, você precisará escapar dos pontos finais na linha FROM em torno de com barras invertidas. O exemplo de código do nosso blog não mostra essas barras invertidas, mas elas estão lá e estão na seção Código-fonte finalamostra de viagem
Apenas para esclarecer isso, estamos usando dois métodos diferentes para consultar nosso Couchbase Server.
O primeiro método corresponde ao companhias aéreasUK este é o seu resolvedor. Precisamos retornar uma promessa e, dentro dela, confiar no bucket.querypara usar uma consulta N1QL predefinida que eu dividi linha por linha na variável de instrução para facilitar a leitura. A capacidade de executar esse tipo de consulta SQL é muito poderosa para um banco de dados de documentos. Muito do SQL que conhecemos é transferido e isso é um grande alívio em comparação com outros bancos de dados de documentos que têm uma API totalmente nova e uma linguagem de consulta que você precisará aprender.
O segundo método corresponde ao companhias aéreasUK este é o seu resolvedor. Precisamos retornar uma promessa e, dentro dela, confiar no bucket.get e, nesse caso, estamos apenas definindo a chave do nosso documento. Lembre-se de que uma das vantagens de usar um armazenamento de dados de valor-chave é que podemos escolher facilmente um único documento com pouca sobrecarga.
Cada um dos métodos acima também testa os erros de consulta e os resolve ou rejeita com base em um resultado ou erro.
Criando nosso GraphQL com o Express Server
Agora que temos tudo organizado para nossos endpoints e consultas, tudo o que precisamos fazer é uso nosso servidor Express e fornecer a ele uma porta para execução, vamos fazer isso agora.
Adicione o seguinte código ao final do nosso servidor.js file:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* A função graphqlHTTP aceita um esquema, rootValue e graphiql entre outras opções para configurar nosso servidor GraphQL */ const serverPort = 4000 const serverUrl = '/graphql' aplicativo.uso(serverUrl, graphqlHTTP({ esquema: esquema, rootValue: raiz, gráfico: verdadeiro })) aplicativo.ouvir( serverPort, () => console.registro(`GraphQL servidor em execução: https://localhost:${serverPort}${serverUrl}`) ) |
Se você já criou um servidor Express ou Express-GraphQL, esse código deve lhe parecer familiar.
Primeiro, configuramos nossa porta e o URL do GraphQL.
Em seguida, passamos nosso esquema GraphQL e seus resolvedores e definimos nosso gráfico para true. (Isso nos dará um IDE para testar nossas consultas GraphQL disponíveis em localhost:4000/graphql.
Por fim, escutamos na porta 4000 e definimos uma mensagem no console para indicar que nosso servidor está em execução.
Vamos executar nosso servidor e garantir que seu Couchbase:
|
1 |
nó servidor |
Assim que tivermos o servidor GraphQL em execução, poderemos testar o Companhias aéreasUK colando o código a seguir no painel de consulta do GraphQL IDE:
|
1 2 3 4 5 6 7 8 9 10 |
consulta getAirlinesUK{ companhias aéreasUK { id nome indicativo país iata icao } } |
Como a consulta indica, ele recuperará todas as nossas companhias aéreas baseadas no Reino Unido:

Em seguida, usaremos o companhia aéreaByKey neste exemplo, também precisaremos criar uma variável de consulta e colá-la no respectivo painel:
|
1 2 3 4 5 6 7 8 9 10 |
consulta getAirlineByKey($id: Int!) { companhia aéreaByKey(id:$id){ id nome indicativo país iata icao } } |
|
1 2 3 |
{ "id": 112 } |
Com isso em mãos, podemos consultar novamente e recuperar um único documento da companhia aérea por chave:

Com uma configuração super simples da API GraphQL, estamos prontos para criar nosso aplicativo react que usará esses endpoints para uma página mestre de detalhes usando as companhias aéreas do Reino Unido em um componente de lista e, quando clicarmos em uma companhia aérea específica, outro componente mostrará os detalhes completos da companhia aérea no lado direito da página.