Pollito Blog
November 26, 2024

La opinión de Pollito acerca del desarrollo en Spring Boot 9: Next.js?

Posted on November 26, 2024  •  5 minutes  • 974 words  • Other languages:  English

Un poco de contexto

Esta es la décima parte de la serie de blogs Spring Boot Development .

¡Comencemos!

Sé algo de frontend

No soy un desarrollador frontend, no participo en actividades de desarrollo frontend en mi día a día.

Dicho eso, sí sé algo de frontend:

Pero mis mayores maestros en frontend (especialmente React) son: Theo , Josh , and Midudev .

¿Cómo encaré este desafío?

Como mi gusto y conocimiento sobre UI/UX no son muy buenos, elegí soluciones prefabricadas.

Pero la librería más importante que usé fue Orval RESTful client generator

Desarrollo impulsado por contratos en una app Next.js

En la página Orval Overview encontramos lo siguiente:

Orval is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification

Y en la página OpenAPI Generator Overview , la herramienta que usamos en el microservicio Java Spring Boot para crear una API siguiendo los principios del Desarrollo impulsado por contratos , encontramos lo siguiente:

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (both 2.0 and 3.0 are supported)

Pareciera que es posible implementar Desarrollo impulsado por contratos en una app Next.js. Veamos cómo se hizo.

1. Orval configuration

En orval.config.ts :

import { defineConfig } from "orval";

export default defineConfig({
  users: {
    output: {
      mode: "split",
      target: "src/__generated__/api/users/usersApi.ts",
      schemas: "src/__generated__/api/users/model",
      client: "react-query",
    },
    input: {
      target: "src/openapi/userManagerBackend.yaml",
    },
  },
});

2. prebuild script en package.json

"prebuild": "npm run orval-build",

3. Ejemplo de uso

En la OpenAPI Specification , existe una operación llamada findById.

/users/{id}:
  get:
    tags:
      - User
    summary: Get user by identifier
    operationId: findById
    parameters:
      - description: User identifier
        in: path
        name: id
        required: true
        schema:
          format: int64
          type: integer
    responses:
      '200':
        description: A user
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
      default:
        description: Error
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Error'

Durante pre-build, Orval generó una función useFindById. Aquí tienes un ejemplo de cómo utilizarlo:

src/app/users/[id]/page.tsx

"use client";
import { useParams } from "next/navigation";
import { getId } from "./_utils/params-utils";
import Loading from "@/components/v0/loading";
import AxiosErrorAlert from "@/components/v0/axios-error-alert";
import UserCard from "./_components/user-card";
import RedirectButton from "@/components/v0/redirect-button";
import { useFindById } from "@/__generated__/api/users/usersApi";

const UserDetails = () => {
  const id = getId(useParams<{ id: string }>());
  const {
    isPending,
    isError,
    data: response,
    error,
  } = useFindById(id, {
    axios: { baseURL: process.env.NEXT_PUBLIC_API_USERS_BASE_URL },
  });

  if (isPending) {
    return <Loading />;
  }

  if (isError) {
    return <AxiosErrorAlert axiosError={error} />;
  }

  return (
    <div className="flex flex-col items-center pt-4">
      <div className="flex flex-col items-center gap-4 w-full max-w-md">
        <UserCard user={response.data} />
        <div className="w-full flex justify-end">
          <RedirectButton href="/users" label="See Users" />
        </div>
      </div>
    </div>
  );
};

export default UserDetails;

Despliegue

No se complique demasiado y simplemente despliegue en un plan gratuito de Vercel . No olvide agregar los secretos de ENV para apuntar al backend y el tamaño de paginación (prefiero tenerlo como algo global).

.env.example

NEXT_PUBLIC_API_USERS_BASE_URL=https://user-manager-backend-den3.onrender.com
NEXT_PUBLIC_API_USERS_PAGE_SIZE=5

Y eso es todo

Fue un largo viaje, que comenzó en diciembre de 2023 con blogs antiguos (ahora eliminados), que trataban los mismos conceptos que traté en esta serie, Principios del Desarrollo impulsado por contratos.

Screenshot2024-11-26195802

Hay algunos pequeños problemas que solucionar aquí y allá:

De todas formas, estoy contento con el resultado tal como está ahora.

Te invito a que leas más cosas en mi blog, ya que mi pasión por el desarrollo web me mantendrá escribiendo blogs con seguridad.

Saludos! Pollito <🐤/>.

Hey, check me out!

You can find me here