Disclaimer: ESBuild por si solo no es suficiente para desarrollo backend. En este artículo se cubre un caso puntual en el que tener todo el código transpilado en un solo archivo no refleja ser un problema.
Backend para consumir una API externa y poder controlar el consumo.
En este caso la API pública de IMDB:
Empecemos
Iniciar proyecto:
mkdir ts-backend
cd ts-backend
pnpm init
Del proyecto:
pnpm add -E fastify
En este caso se usará fastify, aunque podría ser cualquier framework.
De desarrollo:
pnpm add -D -E @types/node esbuild
package.json
Script para compilar el proyecto:
build.js
import esbuild from "esbuild";
esbuild.build({
entryPoints: ["src/index.ts"],
bundle: true,
platform: "node",
format: "esm",
outfile: ".out/index.js",
external: ["fastify"],
});
Es necesario añadir fastify como externo para que esbuild no lo considere al momento de transpilar.
Ahora modificar el package.json
con las siguientes propiedades:
{...
"type": "module",
"scripts": {
"build": "node build.js",
"start": "node .out/index.js"
},
...}
Crear el script principal para levantar el proyecto:
src/index.ts
import Fastify from "fastify";
const fastify = Fastify();
fastify.get("/", () => {
return { hi: "you" };
});
fastify.listen({ port: 8080 });
Ahora toca levantar el servidor con los siguientes comandos:
pnpm run build
pnpm run start
Respuesta:
// http://localhost:8080/
{
"hi": "you"
}
Bastaría con añadir el controlador para consumir la API:
type Movie = {
title: string;
year: string;
url: string;
};
fastify.get("/search-movie/:query", async (request) => {
const q = (request.params as { query: string }).query;
const res = await fetch(`https://search.imdbot.workers.dev/?q=${q}`);
const data = await res.json();
const movies: Movie[] = data.description?.map((movie) => ({
title: movie["#TITLE"],
year: movie["#YEAR"],
url: movie["#IMDB_URL"],
}));
return movies;
});
Levantamos el servidor nuevamente y la respuesta tendría el siguiente formato:
// http://localhost:8080/search-movie/star-wars
[
{
"title": "Star Wars: The Bad Batch",
"year": 2021,
"url": "https://imdb.com/title/tt12708542"
},
{
"title": "Star Wars: Episode IV - A New Hope",
"year": 1977,
"url": "https://imdb.com/title/tt0076759"
},
...
Por ir directo al punto, salteé partes importantes a considerar.
Por seguridad es necesario configurar el CORS, para ello se puede utilizar @fastify/cors
.
Para la experiencia de desarrollo quedan muchas cosas en el aire, por ejemplo las siguientes dependencias podrían servir de ayuda:
src
.supervisor
.Utilizo esta forma de hacer backend para consumir la API de Gemini Pro. Verifica la autenticación y cantidad de consultas disponibles por usuario a la API.
No confíen en la respuesta de Gemini, pero es cierto que no es escalable. Para este caso puntual, es más que suficiente.