Construindo uma API com funções Gatsby
Publicados: 2022-03-10Você 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:
- O front-end não suportava funções sem servidor.
- 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.
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 +”.
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
.
Como mencionado acima, o Gatsby Cloud pode se conectar ao GitHub, GitLab ou Bitbucket. Selecione seu provedor Git preferido e clique em next
.
Com seu provedor Git conectado, você pode pesquisar seu repositório e dar um nome ao seu site.
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.
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
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
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
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
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.
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.
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.
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.