Endpoints en Astro

Rutas personalizadas para usar como endpoints


Hasta el momento, hemos visto como hacer rutas estáticas y rutas dinámicas. Sin embargo, existen otros casos que podrían resultarnos útiles y se escapan un poco de estos dos tipos de rutas: los endpoints.

¿Qué son los Endpoints?

Imagina que en lugar de querer crear una ruta a una página, quieres crear una ruta a otro tipo de archivo:

  • 1️⃣ Una imagen.
  • 2️⃣ Un archivo .json o .xml.
  • 3️⃣ Una API que responda con .json.

En estos casos es donde, probablemente, te interese crear endpoints en lugar de rutas estáticas o dinámicas.

¿Cómo crear un Endpoint en Astro?

Crear un endpoint en Astro es muy sencillo. Simplemente debemos crear un fichero en src/pages, sólo que en lugar de extensión .astro debe tener la extensión a utilizar y una doble extensión y terminar en .js o .ts.

Veamos algunos ejemplos.

Por ejemplo, si queremos crear un fichero .json, crearemos el archivo src/pages/author.json.js, que se encargará de crear la ruta final en nuestra web /author.json.

Para crear este endpoint, necesitaremos lo siguiente:

const content = {
  name: "ManzDev",
  role: "streamer",
  site: "https://manz.dev/"
};

export function GET() {
  return new Response(JSON.stringify(content));
}

Veamos como ha sido la implementación:

  • 1️⃣ Creamos la información en un . En nuestro ejemplo, content.
  • 2️⃣ Exportamos la función GET() (en mayúsculas).
  • 3️⃣ Devolvemos nuestra respuesta con new Response() y el contenido a devolver.
  • 4️⃣ Usamos JSON.stringify() para convertirlo en texto.

Veamos otro ejemplo, un poco más complejo, donde vamos a construir una imagen SVG. El nombre del archivo será src/pages/image.svg.js y veamos primero el código:

const headers = {
  "Content-Type": "image/svg+xml",
}

const svg = /* svg */`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 107 107">
  <path d="m 37.6,91.1 c -4.8,-4.4 -6.3,-13.7 -4.2,-20.4 3.5,4.2 8.3,5.6
    13.3,6.3 7.7,1.2 15.3,0.8 22.5,-2.8 0.8,-0.4 1.6,-0.9 2.5,-1.4 0.7,1.9
    0.9,3.9 0.6,5.9 -0.6,4.9 -3,8.7 -6.9,11.5 -1.5,1.2 -3.2,2.2 -4.8,3.3
    -4.9,3.3 -6.2,7.2 -4.4,12.9 0.1,0.1 0.1,0.3 0.2,0.6 -2.5,-1.1 -4.3,-2.8
    -5.7,-4.9 -1.5,-2.3 -2.2,-4.8 -2.2,-7.5 0,-1.3 0,-2.7 -0.2,-4 -0.5,-3.1
    -2,-4.6 -4.8,-4.7 -2.8,0 -5.1,1.7 -5.7,4.6 -0.1,0.2 -0.1,0.4 -0.2,0.6z"
    fill="#D83333" />
  <path d="m 10,69.6 c 0,0 14.3,-7 28.7,-7 L 49.5,29.1 c 0.4,-1.6 1.6,-2.7
    2.9,-2.7 1.3,0 2.5,1.1 2.9,2.7 l 10.9,33.5 c 17,0 28.6,7 28.6,7 C 94.8,69.6
    70.5,3.4 70.5,3.2 69.8,1.3 68.6,0 67,0 H 37.8 C 36.2,0 35.1,1.3 34.4,3.2
    34.3,3.3 10,69.6 10,69.6Z" fill="#222" />
</svg>`;

export function GET() {
  return new Response(svg, { headers });
}

Repasemos la implementación:

  • 1️⃣ Creamos una cabecera headers con el tipo MIME del SVG: image/svg+xml.
  • 2️⃣ Creamos el contenido del archivo. Un svg con el contenido de texto.
  • 3️⃣ Por último, devolvemos en el Response() el contenido y las cabeceras.

Vamos con otro ejemplo más. En este caso, no será texto, y hay un poco más de magia aprovechando que Astro ejecuta este código en desarrollo, por lo que tenemos acceso a herramientas de Node.

Veamos primero el código:

import sharp from "sharp";

const headers = {
  "Content-Type": "image/png",
}

const svg = /* svg */`<svg id="html" viewBox="0 0 300 300">
  <path fill="#e34f26" d="M50 264 28 13h246l-22 251-101 28" />
  <path fill="#ef652a" d="m151 270 82-22 19-215H151" />
  <path fill="#ebebeb" d="M151 126h-41l-2-31h43V64H74v8l8 85h69zm0
    80-35-9-2-24H84l3 48 64 18z" />
  <path fill="#fff" d="M151 126v31h38l-4 40-34 9v33l63-18 1-5 7-82
    1-8h-9zm0-62v31h74l1-7 2-16v-8z" />
</svg>`;

export async function GET() {
  const png = await sharp(Buffer.from(svg)).png().toBuffer();

  return new Response(png, { headers });
}

¿Qué hemos hecho en este caso?

  • 1️⃣ En primer lugar, instalamos Sharp con npm install -D sharp.
  • 2️⃣ Una vez instalado, lo importamos. Recuerda que esto es NodeJS.
  • 3️⃣ En la cabecera, indicamos el MIME del fichero PNG que queremos crear: image/png.
  • 4️⃣ Luego, creamos el código SVG como hicimos en el ejemplo anterior.
  • 5️⃣ Por último, en la primera línea de la función GET() convertimos el svg a png, utilizando buffers para hacerlo compatible.

Endpoints dinámicos en Astro

De la misma forma que hemos hecho endpoints estáticos podemos hacer endpoints dinámicos. Sólo tenemos que unir lo aprendido en el post de rutas dinámicas con lo aprendido en este artículo.

Observa el siguiente fragmento de código:

const usernames = ["Sarah", "Chris", "Yan", "Elian"];

export function GET({ params }) {
  const { username } = params;

  return new Response(
    JSON.stringify({ name: username })
  );
};

export function getStaticPaths() {
  return usernames.map(username => ({ params: { username } }));
}

En este caso, además de la función GET() exportamos una función getStaticPaths() y nombramos a nuestro archivo src/pages/user/[username].json.js. De esta forma, tendremos las siguientes rutas:

/user/Sarah.json
/user/Chris.json
/user/Yan.json
/user/Elian.json

En el interior de cada uno de estos archivos, tendremos un objeto con la propiedad name y el nombre del usuario como valor. Observa que ese username lo obtiene de los params, es decir, de la URL indicada por el usuario, como vimos en el tema de las rutas dinámicas.

Estos sistemas de crear endpoints nos pueden servir para crear archivos de una forma organizada y revisada por el desarrollador. Recuerda que si simplemente te interesa colocar un archivo estático tal cuál, lo ideal es colocarlo en la carpeta public/, ya que se enviará al usuario exactamente igual.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev