Construindo uma API com funções Gatsby

Publicados: 2022-03-10
Resumo rápido ↬ Neste tutorial, Paul Scanlon explica como construir uma API usando Gatsby Functions e o que você precisa ter em mente ao implantá-la no Gatsby Cloud.

Você provavelmente já ouviu falar sobre as funções sem servidor, mas, se não ouviu, as funções sem servidor fornecem funcionalidades normalmente associadas a tecnologias do lado do servidor que podem ser implementadas junto com o código front-end sem ficar preso nas infraestruturas do lado do servidor.

Com o código do lado do servidor e do lado do cliente coexistindo na mesma base de código, desenvolvedores de front-end como eu podem estender o alcance do que é possível usando as ferramentas que eles já conhecem e adoram.

Limitações

A coexistência é ótima, mas há pelo menos dois cenários que encontrei em que o uso de funções sem servidor dessa maneira não era o ajuste certo para a tarefa em questão. Eles são os seguintes:

  1. O front-end não suportava funções sem servidor.
  2. A mesma funcionalidade era exigida por mais de um front-end.

Para ajudar a fornecer algum contexto, aqui está um exemplo dos pontos 1 e 2 mencionados acima. Eu mantenho um projeto de código aberto chamado MDX Embed, você verá no site de documentos que não é um site do Gatsby. Ele foi construído usando o Storybook e o Storybook por conta própria não fornece recursos de função sem servidor. Eu queria implementar contribuições “Pague o que você quiser” para ajudar a financiar este projeto e eu queria usar o Stripe para permitir pagamentos seguros, mas sem um “backend” seguro Isso não teria sido possível.

Ao abstrair essa funcionalidade em uma API construída com Gatsby Functions, consegui alcançar o que queria com o MDX Embed e também reutilizar a mesma funcionalidade e habilitar a funcionalidade “Pague o que quiser” para o meu blog.

Você pode ler mais sobre como eu fiz isso aqui: Monetize Software Open-Source com Gatsby Functions And Stripe.

É neste ponto que o uso do Gatsby Functions pode atuar como uma espécie de Back-end para front-end ou BFF e desenvolver dessa forma é mais parecido com desenvolver uma API ( Application Programming Interface ).

As APIs são usadas pelo código front-end para lidar com coisas como logins, busca de dados em tempo real ou tarefas seguras que não são tratadas adequadamente apenas pelo navegador. Neste tutorial, explicarei como construir uma API usando Gatsby Functions e implantá-la no Gatsby Cloud.

Mais depois do salto! Continue lendo abaixo ↓

Verificações prévias

As funções do Gatsby funcionam quando implantadas no Gatsby Cloud ou Netlify e, neste tutorial, explicarei como implantar no Gatsby Cloud, para que você precise se inscrever e criar uma conta gratuita primeiro.

Você também vai precisar de uma conta GitHub, GitLab ou BitBucket, é assim que o Gatsby Cloud lê seu código e então constrói seu “site”, ou neste caso, API.

Para os propósitos deste tutorial, usarei o GitHub. Se você preferir avançar, o código da API de demonstração finalizado pode ser encontrado no meu GitHub.

Começando

Crie um novo diretório em algum lugar em sua unidade local e execute o seguinte em seu terminal. Isso configurará um package.json padrão.

 npm init -y

Dependências

Digite o seguinte em seu terminal para instalar as dependências necessárias.

 npm install gatsby react react-dom

Páginas

É provável que sua API não tenha nenhuma “página”, mas para evitar ver o aviso de página ausente padrão do Gatsby ao visitar a URL raiz no navegador, adicione o seguinte a src/pages/index.js e src/pages/404.js .

 //src/pages/index.js & src/pages/404.js export default () => null;

API

Adicione o seguinte a src/api/my-first-function.js .

Explicarei um pouco mais tarde o que significa 'Access-Control-Allow-Origin', '*' , mas resumindo, garante que suas APIs de outras origens não sejam bloqueadas pelo CORS.

 //src/api/my-first-function.js export default function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.status(200).json({ message: 'A ok!' }); }

Scripts

Adicione o seguinte ao package.json .

 //package.json ... "scripts": { "develop": "gatsby develop", "build": "gatsby build" }, ...

Inicie o servidor de desenvolvimento Gatsby

Para ativar o servidor de desenvolvimento Gatsby, execute o seguinte em seu terminal.

 npm run develop

Faça uma solicitação do navegador

Com o servidor de desenvolvimento do Gatsby em execução, você pode visitar http://localhost:8000/api/my-first-function, e como esta é uma solicitação GET simples, você deve ver o seguinte em seu navegador.

 { "message": "A ok!" }

Parabéns

Você acabou de desenvolver uma API usando o Gatsby Functions.

Implantar

Se você estiver vendo a resposta acima em seu navegador, é seguro assumir que sua função está funcionando corretamente localmente, nas etapas a seguir, explicarei como implantar sua API no Gatsby Cloud e acessá-la usando uma solicitação HTTP do CodeSandbox.

Empurre o código para o Git

Antes de tentar implantar no Gatsby Cloud, você precisará enviar seu código para o provedor Git de sua escolha.

Gatsby Cloud

Faça login na sua conta do Gatsby Cloud e procure o grande botão roxo que diz “Adicionar site +”.

Captura de tela do site Gatsby Cloud Add
Adicione um site ao Gatsby Cloud. (Visualização grande)

Na próxima etapa, você será solicitado a Importar de um repositório Git ou Iniciar de um modelo, selecione Import from Git Repository e clique em next .

Captura de tela selecionar importação de um repositório Git
Selecione importar de um repositório Git. (Visualização grande)

Como mencionado acima, o Gatsby Cloud pode se conectar ao GitHub, GitLab ou Bitbucket. Selecione seu provedor Git preferido e clique em next .

Captura de tela da seleção do provedor Gatsby Cloud Git
Selecione no seu provedor Git preferido. (Visualização grande)

Com seu provedor Git conectado, você pode pesquisar seu repositório e dar um nome ao seu site.

Captura de tela da pesquisa do Gatsby Cloud para o site do provedor Git
Procure seu site no seu provedor Git. (Visualização grande)

Depois de selecionar seu repositório e nomear seu site, clique em next .

Você pode pular as “Integrações” e “Configuração”, pois não precisaremos delas.

Se tudo foi planejado, você deve estar vendo algo semelhante à captura de tela abaixo.

Captura de tela do site implantado com sucesso
'site' construído e implantado com sucesso no Gatsby Cloud. (Visualização grande)

Você verá perto do topo no lado esquerdo da tela um URL que termina com gatsbyjs.io , este será o URL para sua API e quaisquer funções que você criar podem ser acessadas adicionando /api/name-of-function ao final deste URL.

Por exemplo, a versão implantada completa de my-first-function.js para minha API de demonstração é a seguinte:

API de demonstração: minha primeira função .

Testando sua API

Visitar a URL de sua API é uma coisa, mas não é como as APIs são normalmente usadas. Idealmente, para testar sua API, você precisa fazer uma solicitação para a função de uma origem completamente não relacionada.

É aqui onde res.setHeader('Access-Control-Allow-Origin', '*'); vem em socorro. Embora nem sempre seja desejável permitir que qualquer domínio (site) acesse suas funções, na maioria das vezes, as funções públicas são apenas isso, públicas. Definir o cabeçalho Access Control para um valor de * significa que qualquer domínio pode acessar sua função, sem isso, qualquer domínio que não seja o domínio em que a API está hospedada será bloqueado pelo CORS.

Aqui está um CodeSandbox que usa my-first-function da minha API de demonstração. Você pode bifurcar isso e alterar a URL de solicitação do Axios para testar sua função.

CodeSandbox: minha primeira função

CodeSandbox: minha primeira função
(Visualização grande)

Ficando mais chique

Enviando uma resposta da sua API que diz a message: "A ok!" não é exatamente empolgante, então, na próxima parte, mostrarei como consultar a API REST do GitHub e criar um cartão de perfil pessoal para exibir em seu próprio site usando a API que você acabou de criar, e será mais ou menos assim .

CodeSandbox: cartão de perfil de demonstração

CodeSandbox: cartão de perfil de demonstração
(Visualização grande)

Dependências

Para usar a API REST do GitHub, você precisará instalar o pacote @octokit/rest.

 npm install @octokit/rest

Obter usuário bruto do GitHub

Adicione o seguinte a src/api/get-github-user-raw.js .

 // src/api/get-github-user-raw.js import { Octokit } from '@octokit/rest'; const octokit = new Octokit({ auth: process.env.OCTOKIT_PERSONAL_ACCESS_TOKEN }); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); try { const { data } = await octokit.request(`GET /users/{username}`, { username: 'PaulieScanlon' }); res.status(200).json({ message: 'A ok!', user: data }); } catch (error) { res.status(500).json({ message: 'Error!' }); } }

Token de acesso

Para se comunicar com a API REST do GitHub, você precisará de um token de acesso. Você pode obter isso seguindo as etapas deste guia do GitHub: Criando um token de acesso pessoal.

Variáveis .env

Para manter seu token de acesso seguro, adicione o seguinte a .env.development e .env.production .

 OCTOKIT_PERSONAL_ACCESS_TOKEN=123YourAccessTokenABC

Você pode ler mais sobre as variáveis ​​de ambiente do Gatsby neste guia de Gatsby: Variáveis ​​de Ambiente.

Iniciar servidor de desenvolvimento

Como você fez antes, inicie o servidor de desenvolvimento Gatsby digitando o seguinte em seu terminal.

 npm run develop

Faça uma solicitação do navegador

Com o servidor de desenvolvimento Gatsby em execução, você pode visitar http://localhost:8000/api/get-github-user-raw, e como isso também é uma solicitação GET simples, você deve ver o seguinte em seu navegador. ( Eu removi parte da resposta por brevidade. )

 { "message": "A ok!", "user": { "login": "PaulieScanlon", "id": 1465706, "node_id": "MDQ6VXNlcjE0NjU3MDY=", "avatar_url": "https://avatars.githubusercontent.com/u/1465706?v=4", "gravatar_id": "", "url": "https://api.github.com/users/PaulieScanlon", "type": "User", "site_admin": false, "name": "Paul Scanlon", "company": "Paulie Scanlon Ltd.", "blog": "https://www.paulie.dev", "location": "Worthing", "email": "[email protected]", "hireable": true, "bio": "Jamstack Developer / Technical Content Writer (freelance)", "twitter_username": "pauliescanlon", "created_at": "2012-02-23T13:43:26Z", "two_factor_authentication": true, ... } }

Aqui está um exemplo do CodeSandbox da resposta bruta completa.

CodeSandbox: resposta bruta

CodeSandbox: resposta bruta
(Visualização grande)

Você verá acima que há muitos dados retornados que eu realmente não preciso, esta próxima parte depende completamente de você, pois é sua API, mas achei útil manipular um pouco a resposta da API do GitHub antes de enviá-lo de volta para o meu código frontend.

Se você quiser fazer o mesmo, pode criar uma nova função e adicionar o seguinte a src/api/get-github-user.js .

 // src/api/get-github-user.js import { Octokit } from '@octokit/rest'; const octokit = new Octokit({ auth: process.env.OCTOKIT_PERSONAL_ACCESS_TOKEN }); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); try { const { data } = await octokit.request(`GET /users/{username}`, { username: 'PaulieScanlon' }); res.status(200).json({ message: 'A ok!', user: { name: data.name, blog_url: data.blog, bio: data.bio, photo: data.avatar_url, githubUsername: `@${data.login}`, githubUrl: data.html_url, twitterUsername: `@${data.twitter_username}`, twitterUrl: `https://twitter.com/${data.twitter_username}` } }); } catch (error) { res.status(500).json({ message: 'Error!' }); } }

Você verá acima que, em vez de retornar o objeto de dados completo retornado pela API REST do GitHub, escolho apenas os bits de que preciso, renomeio-os e adiciono alguns bits antes dos valores de nome de usuário e URL. Isso torna a vida um pouco mais fácil quando você renderiza os dados no código front-end.

Aqui está um exemplo do CodeSandbox da resposta formatada.

CodeSandbox: resposta formatada

CodeSandbox: resposta formatada
(Visualização grande)

Isso é muito semelhante ao CodeSandbox do cartão de perfil anterior, mas também imprimi os dados para que você possa ver como cada item de dados manipulado é usado.

Vale a pena notar neste ponto que todas as quatro demonstrações do CodeSandbox neste tutorial estão usando a API de demonstração, e nenhuma delas é construída usando o Gatsby ou hospedada no Gatsby Cloud - legal!

Variáveis .env no Gatsby Cloud

Antes de implantar suas duas novas funções, você precisará adicionar o token de acesso do GitHub à seção de variáveis ​​de ambiente no Gatsby Cloud.

Captura de tela do Gatsby Cloud com configurações do site
(Visualização grande)

Onde ir a partir daqui?

Eu me fiz essa mesma pergunta. Normalmente, as funções sem servidor são usadas em solicitações do lado do cliente e, embora isso seja bom, eu me perguntei se elas também poderiam ser usadas em tempo de compilação para "cozinhar" dados estaticamente em uma página, em vez de depender de JavaScript, que pode ou não ser desabilitado no usuário. navegador.

…então foi exatamente isso que eu fiz.

Aqui está um tipo de painel de dados que usa dados retornados pelo Gatsby Functions em tempo de execução e compilação. Eu construí este site usando o Astro e o implantei no GitHub Pages.

A razão pela qual eu acho que essa é uma ótima abordagem é porque posso reutilizar a mesma funcionalidade no servidor e no navegador sem duplicar nada.

Nesta compilação do Astro, atingi o mesmo endpoint exposto pela minha API para retornar dados que são inseridos na página (ótimo para SEO) ou buscados em tempo de execução pelo navegador (ótimo para mostrar dados atualizados ou atualizados ao minuto) .

Painel de dados

Os dados exibidos à esquerda do site são solicitados no momento da construção e inseridos na página com o Astro. Os dados à direita da página são solicitados em tempo de execução usando uma solicitação do lado do cliente. Eu usei endpoints ligeiramente diferentes expostos pela API REST do GitHub para consultar diferentes contas de usuário do GitHub que criam as diferentes listas.

Painel de dados
(Visualização grande)

Tudo o que você vê neste site é fornecido pela minha API mais completa. Eu a chamei: API Paulie e eu a uso em vários dos meus sites.

API Paulie

Paulie API como a API deste tutorial é construída com Gatsby, mas como Gatsby pode atuar como um site e uma API eu a usei para documentar como todas as minhas funções funcionam e cada endpoint tem sua própria página que pode ser usada como um playground… sinta-se à vontade para dar uma olhada.

API Paulie
(Visualização grande)

Então, aí está, uma API do Gatsby Functions que pode ser usada por qualquer código do lado do cliente ou do lado do servidor, a partir de qualquer site construído com qualquer pilha de tecnologia.

Dê uma chance e eu ficaria muito interessado em ver o que você constrói. Sinta-se à vontade para compartilhar nos comentários abaixo ou venha me encontrar no Twitter: @PaulieScanlon.