Cómo crear una API de REST con Prisma y PostgreSQL
El autor seleccionó la organización Diversity in Tech Fund para que reciba una donación como parte del programa Write for DOnations.
Introducción
Prisma es un conjunto de herramientas para bases de datos de código abierto. Consta de tres herramientas principales:
- Prisma Client: un generador de consultas con seguridad de tipos que se genera de forma automática para Node.js y TypeScript.
- Prisma Migrate: un sistema de migración y modelado de datos declarativo.
- Prisma Studio: una GUI para ver y editar datos en su base de datos.
Estas herramientas pretenden aumentar la productividad de los desarrolladores de aplicaciones en los flujos de trabajo de sus bases de datos. Uno de los principales beneficios de Prisma es el nivel de abstracción que proporciona: en lugar de tener que resolver consultas SQL o migraciones de esquemas complejas, los desarrolladores de aplicaciones pueden razonar acerca de sus datos de forma más intuitiva al utilizar Prisma para trabajar con su base de datos.
En este tutorial, creará una API de REST para una aplicación de blog pequeña en TypeScript usando Prisma y una base de datos PostgreSQL. Configurará su base de datos PostgreSQL de forma local con Docker e implementará las rutas de la API de REST utilizando Express. Al final del tutorial, tendrá un servidor web que puede responder a varias solicitudes HTTP y leer y escribir datos en la base de datos ejecutándose en su equipo de forma local.
Requisitos previos
Para seguir este tutorial, necesitará lo siguiente:
- Node.js v10 o superior instalado en su equipo. Para instalarlo, puede utilizar una de las guías de Cómo instalar Node.js y crear un entorno de desarrollo local para su sistema operativo.
- Docker instalado en su equipo (para ejecutar la base de datos PostgreSQL). Puede descargar versiones para macOS y Windows en el sitio web de Docker o seguir la guía Cómo instalar y usar Docker para distribuciones de Linux.
Es útil, pero no un requisito de este tutorial, tener conocimientos básicos sobre TypeScript y las API de REST.
Paso 1: Crear su proyecto de TypeScript
En este paso, configurará un proyecto de TypeScript simple utilizando npm
. Este proyecto será la base para la API de REST que creará en el transcurso de este tutorial.
Primero, cree un directorio nuevo para su proyecto:
Luego, diríjase al directorio e inicie un proyecto npm
vacío. Tenga en cuenta que la opción -y
se utiliza para omitir las solicitudes interactivas del comando. Para verlas, elimine -y
del comando:
Para obtener más información sobre estas solicitudes, siga el Paso 1 de Cómo usar módulos Node.js con npm y package.json.
Obtendrá un resultado similar al siguiente con las respuestas predeterminadas:
OutputWrote to /.../my-blog/package.json:
{
"name": "my-blog",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Este comando crea un archivo package.json
mínimo que utiliza como archivo de configuración de su proyecto npm
. Con esto, está listo para configurar TypeScript en su proyecto.
Ejecute el siguiente comando para realizar la instalación básica de TypeScript:
Este comando instala tres paquetes como dependencias de desarrollo en su proyecto:
typescript
: la cadena de herramientas de TypeScript.ts-node
: un paquete para ejecutar aplicaciones TypeScript sin compilar previamente a JavaScript.@types/node
: las definiciones de tipo de TypeScript para Node.js.
Solo resta añadir un archivo tsconfig.json
para garantizar que TypeScript esté configurado de forma adecuada para la aplicación que va a crear.
Primero, ejecute el siguiente comando para crear el archivo:
Agregue el siguiente código de JSON al archivo:
Guarde el archivo y ciérrelo.
Esta es una configuración estándar y mínima para un proyecto de TypeScript. Puede encontrar información sobre las propiedades individuales del archivo de configuración en la documentación de TypeScript.
Ha configurado su proyecto de TypeScript simple usando npm
. A continuación, configurará su base de datos PostgreSQL con Docker y la conectará a Prisma.
Paso 2: Configurar Prisma con PostgreSQL
En este paso, instalará la CLI de Prisma, creará su archivo de esquema de Prisma inicial, configurará PostgreSQL con Docker y conectará Prisma a la base de datos. El archivo de esquema de Prisma es el archivo de configuración principal de su instalación de Prisma y contiene el esquema de su base de datos.
Comience por instalar la CLI de Prisma con el siguiente comando:
Se recomienda instalar la CLI de Prisma en el proyecto de forma local (en lugar de realizar una instalación global). Esto ayuda a evitar conflictos de versiones en caso de que tenga más de un proyecto de Prisma en su equipo.
A continuación, configurará su base de datos PostgreSQL utilizando Docker. Cree un nuevo archivo de Docker Compose con el siguiente comando:
Luego, añada el siguiente código al archivo nuevo:
Este archivo de Docker Compose configura una base de datos PostgreSQL a la que se puede acceder a través del puerto 5432
del contenedor de Docker. Tenga en cuenta que estamos utilizando las credenciales de la base de datos sammy
(usuario) y your_password
(contraseña). Puede modificar estas credenciales y utilizar el nombre de usuario y la contraseña que desee. Guarde el archivo y ciérrelo.
Ahora que estableció esta configuración, proceda a iniciar el servidor de la base de datos PostgreSQL con el siguiente comando:
El resultado de este comando será similar al siguiente:
OutputPulling postgres (postgres:10.3)...
10.3: Pulling from library/postgres
f2aa67a397c4: Pull complete
6de83ca23e55: Pull complete
. . .
Status: Downloaded newer image for postgres:10.3
Creating my-blog_postgres_1 ... done
Puede verificar que el servidor de la base de datos se esté ejecutando con el siguiente comando:
Obtendrá un resultado similar al siguiente:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8547f8e007ba postgres:10.3 "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 0.0.0.0:5432->5432/tcp my-blog_postgres_1
Ahora que el servidor de la base de datos está en ejecución, puede crear su instalación de Prisma. Ejecute el siguiente comando desde la CLI de Prisma:
Esto imprimirá el siguiente resultado:
Output✔ Your Prisma schema was created at prisma/schema.prisma.
You can now open it in your favorite editor.
Tenga en cuenta que es recomendable prefijar todas las invocaciones de la CLI de Prisma con npx
. Esto garantiza que se utilice su instalación local.
Cuando ejecutó el comando, la CLI de Prisma creó una nueva carpeta denominada prisma
en su proyecto. Contiene estos dos archivos:
schema.prisma
: el archivo de configuración principal de su proyecto de Prisma (incluirá su modelo de datos)..env
: un archivo dotenv para definir la URL de conexión de su base de datos.
Para asegurarse de que Prisma conozca la ubicación de su base de datos, abra el archivo .env
y ajuste la variable de entorno DATABASE_URL
.
Primero, abra el archivo .env
:
Ahora, puede establecer la variable de entorno de la siguiente manera:
DATABASE_URL="postgresql://sammy:your_password@localhost:5432/my-blog?schema=public"
Asegúrese de reemplazar las credenciales de la base de datos por las que especificó en el archivo de Docker Compose. Para obtener más información sobre el formato de la URL de conexión, consulte la documentación de Prisma.
Cuando termine, guarde y cierre el archivo.
En este paso, configuró su base de datos PostgreSQL con Docker, instaló la CLI de Prisma y conectó a la base de datos a través de una variable de entorno. En la siguiente sección, definirá el modelo de datos y creará las tablas de su base de datos.
Paso 3: Definir el modelo de datos y crear tablas de datos
En este paso, definirá el modelo de datos en el archivo de esquema de Prisma. Luego, asignará ese modelo de datos a la base de datos con Prisma Migrate, que generará y enviará las instrucciones SQL para crear las tablas correspondientes a su modelo de datos. Como está creando una aplicación de blog, las principales entidades de la aplicación serán usuarios y publicaciones.
Prisma utiliza su propio lenguaje de modelado de datos para definir la forma de los datos de su aplicación.
Primero, abra el archivo schema.prisma
con el siguiente comando:
Luego, añada las siguientes definiciones del modelo allí. Puede colocar los modelos en la parte inferior del archivo, justo después del bloque generator client
:
. . .
model User {
id Int @default(autoincrement()) @id
email String @unique
name String?
posts Post[]
}
model Post {
id Int @default(autoincrement()) @id
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
Guarde el archivo y ciérrelo.
Está definiendo dos modelos, denominados User
y Post
. Cada uno de ellos contiene varios campos que representan las propiedades del modelo. Los modelos se asignarán a las tablas de la base de datos; los campos representan las columnas individuales.
Tenga en cuenta que hay una relación de uno a varios entre los dos modelos, especificada por los campos de relaciones posts
y author
en User
y Post
. Esto significa que se puede asociar un usuario a varias publicaciones.
Ahora que estableció estos modelos, puede crear las tablas correspondientes en la base de datos utilizando Prisma Migrate. Ejecute el siguiente comando en su terminal:
Este comando crea una migración nueva en su sistema de archivos. A continuación, se presenta una descripción general de las tres opciones que se proporcionan al comando:
--experimental
: se requiere porque, actualmente, Prisma Migrate está en estado experimental.--create-db
: permite a Prisma Migrate crear la base de datos denominadamy-blog
especificada en la URL de conexión.--name "init"
: especifica el nombre de la migración (se utilizará para dar nombre a la carpeta de migración que se crea en su sistema de archivos).
El resultado de este comando será similar al siguiente:
OutputNew datamodel:
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @default(autoincrement()) @id
email String @unique
name String?
posts Post[]
}
model Post {
id Int @default(autoincrement()) @id
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
Prisma Migrate just created your migration 20200811140708-init in
migrations/
└─ 20200811140708-init/
└─ steps.json
└─ schema.prisma
└─ README.md
Puede ver los archivos de migración que se crearon en el directorio prisma/migrations
.
Para ejecutar la migración de su base de datos y crear las tablas para sus modelos de Prisma, ejecute el siguiente comando en su terminal:
Obtendrá el siguiente resultado:
Output. . .
Checking the datasource for potential data loss...
Database Changes:
Migration Database actions Status
20200811140708-init 2 CreateTable statements. Done 🚀
You can get the detailed db changes with prisma migrate up --experimental --verbose
Or read about them here:
./migrations/20200811140708-init/README.md
🚀 Done with 1 migration in 206ms.
Ahora, Prisma Migrate generará las instrucciones SQL necesarias para la migración y las enviará a la base de datos. Estas son las instrucciones SQL que crearon las tablas:
En este paso, definió su modelo de datos en el esquema de Prisma y creó las respectivas tablas de bases de datos con Prisma Migrate. En el siguiente paso, instalará Prisma Client en su proyecto para poder consultar la base de datos.
Paso 4: Explorar consultas de Prisma Client en una secuencia de comandos simple
Prisma Client es un generador de consultas con seguridad de tipos de generación automática que puede utilizar para leer y escribir datos mediante programación en una base de datos desde una aplicación Node.js o TypeScript. Lo utilizará para acceder a la base de datos con las rutas de su API de REST, en lugar de usar ORM tradicionales, consultas SQL simples, capas de acceso a datos personalizadas o cualquier otro método de comunicación con una base de datos.
En este paso, instalará Prisma Client y se familiarizará con las consultas que puede enviar. Antes de implementar las rutas de su API de REST en los siguientes pasos, analizaremos algunas consultas de Prisma Client en una secuencia de comandos ejecutable simple.
Primero, para instalar Prisma Client en su proyecto, abra su terminal e instale el paquete npm
de Prisma Client:
A continuación, cree un directorio nuevo denominado src
para alojar sus archivos de origen:
Ahora, cree un archivo de TypeScript en el directorio nuevo:
Todas las consultas de Prisma Client devuelven promesas con las que puede usar await
en su código. Para hacerlo, deberá enviar las consultas dentro de una función async
.
Añada el siguiente código reutilizable con una función async
que se ejecute en su secuencia de comandos:
A continuación, se presenta una descripción general del código reutilizable:
- Se importa el constructor
PrismaClient
del paquetenpm
@prisma/client
previamente instalado. - Se inicia
PrismaClient
al invocar al constructor y se obtiene una instancia denominadaprisma
. - Se define una función
async
denominadamain
en la que, a continuación, añadirá las consultas de Prisma Client. - Se invoca la función
main
y, a la vez, se detectan posibles excepciones y se garantiza que Prisma Client cierre cualquier conexión con bases de datos abierta al invocarprisma.disconnect()
.
Ahora que estableció la función main
, puede comenzar a añadir consultas de Prisma Client a la secuencia de comandos. Ajuste index.ts
para que tenga el siguiente aspecto:
En este código, está utilizando dos consultas de Prisma Client:
create
: crea un nuevo registro deUser
. Tenga en cuenta que, en realidad, está utilizando una escritura anidada, lo que significa que está creando un registro deUser
y uno dePost
en la misma consulta.findMany
: lee todos los registros deUser
existentes de la base de datos. Está proporcionando una opcióninclude
, que, adicionalmente, carga los registros dePost
relacionados de cada registro deUser
.
A continuación, ejecute la secuencia de comandos con el siguiente comando:
Obtendrá el siguiente resultado en su terminal:
OutputCreated new user: { id: 1, email: 'alice@prisma.io', name: 'Alice' }
[
{
id: 1,
email: 'alice@prisma.io',
name: 'Alice',
posts: [
{
id: 1,
title: 'Hello World',
content: null,
published: false,
authorId: 1
}
]
}
Nota: Si está utilizando una GUI de base de datos, puede verificar que los datos se hayan creado al revisar las tablas User
y Post
. De forma alternativa, puede consultar los datos de Prisma Studio al ejecutar npx prisma studio --experimental
.
Ha aprendido a utilizar Prisma Client para leer y escribir datos en su base de datos. En los siguientes pasos, aplicará sus conocimientos nuevos para implementar las rutas de una API de REST de muestra.
Paso 5: Implementar su primera ruta de la API de REST
En este paso, instalará Express en su aplicación. Express es un marco web popular para Node.js que utilizará para implementar sus rutas de la API de REST en este proyecto. La primera ruta que implementará le permitirá obtener todos los usuarios de la API utilizando una solicitud GET
. Obtendrá los datos de los usuarios de la base de datos utilizando Prisma Client.
Instale Express con el siguiente comando:
Como está utilizando TypeScript, también le convendrá instalar los respectivos tipos como dependencias de desarrollo. Para hacerlo, ejecute el siguiente comando:
Ahora que estableció las dependencias, puede configurar su aplicación Express.
Comience por volver a abrir su archivo de origen principal:
A continuación, elimine todo el código de index.ts
y sustitúyalo por el siguiente para iniciar su API de REST:
A continuación, se presenta una descripción breve del código:
- Se importan
PrismaClient
yexpress
de sus respectivos paquetesnpm
. - Se inicia
PrismaClient
al invocar al constructor y se obtiene una instancia denominadaprisma
. - Su aplicación Express se crea al invocar
express()
. - Se añade el software intermedio
express.json()
para garantizar que Express pueda procesar correctamente los datos de JSON. - Se inicia el servidor en el puerto
3000
.
Con esto, puede implementar su primera ruta. Agregue el siguiente código entre las invocaciones a app.use
y app.listen
:
Una vez que lo haya añadido, guarde y cierre su archivo. A continuación, inicie su servidor web local utilizando el siguiente comando:
Recibirá el siguiente resultado:
OutputREST API server ready at: http://localhost:3000
Para acceder a la ruta /users
, puede apuntar su navegador a http://localhost:3000/users
o a cualquier otro cliente HTTP.
En este tutorial, probará todas las rutas de la API de REST utilizando curl
, un cliente HTTP basado en terminal.
Nota: Si prefiere usar un cliente HTTP basado en GUI, puede usar alternativas como Postwoman o el cliente REST avanzado.
Para probar su ruta, abra una ventana o una pestaña de terminal nueva (para que su servidor web local pueda seguir en ejecución) y ejecute el siguiente comando:
Obtendrá los datos de User
que creó en el paso anterior:
Output[{"id":1,"email":"alice@prisma.io","name":"Alice"}]
Tenga en cuenta que la matriz posts
no se incluye en este momento. Esto se debe a que no está pasando la opción include
a la invocación de findMany
en la implementación de la ruta /users
.
Ha implementado su primera ruta de la API de REST en /users
. En el siguiente paso, implementará las rutas restantes de la API de REST para añadir más funcionalidad a su API.
Paso 6: Implementar las rutas restantes de la API de REST
En este paso, implementará las rutas restantes de la API de REST para su aplicación de blog. Al final, su servidor web proporcionará diversas solicitudes GET
, POST
, PUT
y DELETE
.
A continuación, se presenta una descripción general de las diferentes rutas que implementará:
Método HTTP | Ruta | Descripción |
---|---|---|
GET | /feed | Obtiene todas las publicaciones publicadas. |
GET | /post/:id | Obtiene un publicación específica por su ID. |
POST | /user | Crea un usuario nuevo. |
POST | /post | Crea una publicación nueva (como borrador). |
PUT | /post/publish/:id | Establece el campo published de una publicación en true . |
DELETE | post/:id | Elimina una publicación por su ID. |
Primero, proceda a ejecutar e implementar las rutas GET
restantes.
Abra index.ts
con el siguiente comando:
A continuación, añada el siguiente código después de la implementación de la ruta /users
:
Guarde y cierre su archivo.
Este código implementa las rutas de la API para dos solicitudes GET
:
/feed
: devuelve una lista de las publicaciones publicadas./post/:id
: devuelve una publicación específica por su ID.
Se utiliza Prisma Client en ambas implementaciones. En la implementación de la ruta /feed
, la consulta que envía con Prisma Client filtra todos los registros de Post
en los que la columna published
contiene el valor true
. Además, la consulta de Prisma Client utiliza include
para obtener la información relacionada de author
de cada publicación que se devuelve. En la implementación de la ruta /post/:id
, pasa la ID que se obtiene de la ruta de la URL para poder leer un registro de Post
específico de la base de datos.
Puede detener el servidor al pulsar CTRL+C
en el teclado. A continuación, reinicie el servidor utilizando lo siguiente:
Para probar la ruta /feed
, puede usar el siguiente comando curl
:
Como aún no se ha publicado ninguna publicación, la respuesta es una matriz vacía:
Output[]
Para probar la ruta /post/:id
, puede usar el siguiente comando curl
:
Este comando devolverá la publicación que creó inicialmente:
Output{"id":1,"title":"Hello World","content":null,"published":false,"authorId":1}
A continuación, ejecute las dos rutas de POST
. Añada el siguiente código a index.ts
después de las implementaciones de las tres rutas de GET
:
Cuando termine, guarde y cierre el archivo.
Este código implementa las rutas de la API para dos solicitudes POST
:
/user
: crea un usuario nuevo en la base de datos./post
: crea una publicación nueva en la base de datos.
Al igual que anteriormente, se utiliza Prisma Client en ambas implementaciones. En la implementación de la ruta /user
, pasa los valores del cuerpo de la solicitud HTTP a la consulta create
de Prisma Client.
La ruta /post
es un poco más compleja: como no puede pasar los valores del cuerpo de la solicitud HTTP directamente, primero, deberá extraerlos de forma manual para pasarlos a la consulta de Prisma Client. Esto se debe a que la estructura de JSON en el cuerpo de la solicitud no coincide con la que espera Prisma Client, por lo tanto, debe crear la estructura esperada de forma manual.
Puede probar las rutas nuevas al detener el servidor con CTRL+C
. A continuación, reinicie el servidor utilizando lo siguiente:
Para crear un usuario nuevo a través de la ruta /user
, puede enviar la siguiente solicitud POST
con curl
:
Con esto, se creará un usuario nuevo en la base de datos y se imprimirá el siguiente resultado:
Output{"id":2,"email":"bob@prisma.io","name":"Bob"}
Para crear una publicación nueva a través de la ruta /post
, puede enviar la siguiente solicitud POST
con curl
:
Con esto, se creará una publicación nueva en la base de datos que se conectará al usuario con el correo electrónico bob@prisma.io
. Se imprime el siguiente resultado:
Output{"id":2,"title":"I am Bob","content":null,"published":false,"authorId":2}
Por último, puede implementar las rutas PUT
y DELETE
.
Abra index.ts
con el siguiente comando:
A continuación, después de la implementación de las dos rutas de POST
, añada el código resaltado:
Guarde y cierre su archivo.
Este código implementa las rutas de la API para una solicitud PUT
y una DELETE
:
/post/public/:id
(PUT
): publica una publicación por su ID./post/:id
(DELETE
): elimina una publicación por su ID.
Nuevamente, se utiliza Prisma Client en ambas implementaciones. En la implementación de la ruta /post/public/:id
, se obtiene la ID de la publicación que se va a publicar de la URL y se pasa a la consulta update
de Prisma Client. La implementación de la ruta /post/:id
para eliminar una publicación de la base de datos también obtiene la ID de la publicación de la URL y la pasa a la consulta delete
de Prisma Client.
Vuelva a detener el servidor pulsando CTRL+C
en el teclado. A continuación, reinicie el servidor utilizando lo siguiente:
Puede probar la ruta PUT
con el siguiente comando curl
:
Con esto, se publicará la publicación con un valor de ID de 2
. Si reenvía la solicitud /feed
, ahora, esta publicación se incluirá en la respuesta.
Por último, puede probar la ruta DELETE
con el siguiente comando curl
:
Con esto, se eliminará la publicación con un valor de ID de 1
. Para confirmar que la publicación con esta ID se haya eliminado, puede reenviar una solicitud GET
a la ruta /post/1
.
En este paso, implementó las rutas restantes de la API de REST para su aplicación de blog. Ahora, la API responde a diversas solicitudes GET
, POST
, PUT
y DELETE
e implementa la funcionalidad para leer y escribir datos en la base de datos.
Conclusión
En este artículo, creó un servidor para la API de REST con diversas rutas para crear, leer, actualizar y eliminar datos de usuarios y publicaciones para una aplicación de blog. Está utilizando Prisma Client dentro de las rutas de la API para enviar las consultas respectivas a su base de datos.
Como próximo paso, puede implementar rutas de la API adicionales o ampliar el esquema de su base de datos utilizando Prisma Migrate. Asegúrese de consultar la documentación de Prisma para obtener más información sobre los distintos aspectos de Prisma y explorar algunos proyectos de ejemplo listos para ejecutar en el repositorio prisma-examples
utilizando herramientas como GraphQL o API de grPC.
0 comentarios:
Publicar un comentario