Introducción a Payload, un CMS y un marco de aplicaciones sin interfaz gráfica
Payload CMS se describe a sí mismo con valentía como un "CMS y un marco de aplicación sin interfaz gráfica". Aunque no nos referimos a las interfaces de usuario como "interfaces gráficas", sin interfaz gráfica solo se refiere a un marco sin interfaz gráfica exclusiva. Un sistema de gestión de contenido (CMS) es solo un marco que manipula datos estructurados. Si los datos son un blog, entonces el contenido que se administra son publicaciones, por ejemplo.
La página ¿Qué es Payload? presenta bien este dilema y, al mismo tiempo, intenta explicar su propio ángulo. Da en el clavo cuando reconoce que un CMS tiende a “vincular la presentación de su contenido al almacenamiento de su contenido”. En consecuencia, lo que Payload pretende hacer es funcionar con cualquier interfaz que desee utilizar.
A día de hoy, Payload se encuentra entre algunos cambios importantes y la versión 3, por lo que la documentación anterior puede estar desactualizada. Siguiendo las instrucciones como hice yo, obtuve una versión anterior. Sin duda, esto se solucionará. Simplemente consulte su canal de Discord para obtener la información más reciente.
Instalación
Hasta el momento, las opciones de requisitos previos de instalación son un poco limitadas para las bases de datos, pero hay un ejemplo relacional y uno basado en documentos para elegir:

En mi confiable MacBook, instalé un MongoDB comunitario a través de Homebrew:


Luego inicié Mongo agregándolo como un servicio:

Podemos ver la cadena de conexión como la URL, por lo que deberíamos poder configurar la carga útil.
En otra pestaña del navegador, instalé la aplicación Payload:

He creado un proyecto de demostración y pronto estaremos listos para lanzarlo:

Uno de los proyectos de ejemplo falló porque esperaba Discord. Como dije, debido a los próximos cambios, parte de la documentación y los videos aún no coinciden del todo. Eso es bueno, por supuesto: el proyecto es muy activo. Seleccioné la plantilla payload-demo, lo cual estuvo bien.
Luego, “yarn dev” ejecuta el proyecto:

Una vez conectado a MongoDB, se inicia tanto la carga útil de administración (en localhost:3000/admin) como la aplicación de demostración (marcada como aplicación Next.js, el marco React utilizado para la plantilla).
La aplicación Payload
Entrando directamente a la aplicación vemos:

En este punto, no hay contenido, por lo que se lo dirige al panel de administración para comenzar a crear algo. El panel de administración me permite crear un rol de administrador o de usuario, con correo electrónico.
El panel de control en sí mismo ayuda a explicar de qué se trata realmente Payload:

Payload organiza todo en conjuntos de tipos en colecciones. Esto incluye páginas y usuarios. Podemos crear nuevos tipos y comenzar a usarlos inmediatamente, como lo haremos.
Aquí hay una pequeña confusión: para empezar, presiona el enlace “Seed the database” (Iniciar la base de datos) y obtendrás mucho contenido de demostración. Eso limpiará todo lo que ya exista. También necesitas crear una página de “inicio”, de lo contrario solo verás la página de plantilla predeterminada de arriba, lo que quizás te haga pensar que no tienes contenido, cuando sí lo tienes.
Una vez que entendí el sistema, creé un contenido simple, aunque poco inspirado, en un tipo de página:

Una vez que utilice la interfaz de administración para agregar elementos a las colecciones, podrá publicar los cambios (confirmarlos). Esto actualizará automáticamente su sitio.
Haciendo todo en código
En esta etapa, no he hecho mucho más de lo que se podría hacer con, por ejemplo, Publii , que también actúa como un CMS clásico. Sin embargo, hay dos cosas que se destacan en Payload. No solo se puede hablar con él en REST, sino que también se pueden reutilizar partes de Payload que difuminan la distinción entre quién es dueño de qué. Y se puede hacer todo en código, que es a donde vamos ahora.
Por ejemplo, puedes ver que Usuarios es un tipo de colección, disponible para que lo usemos:

¿Y dónde se registran? Todo en el archivo. Primero se importan y luego (como puede ver a continuación) se agregan a las colecciones conocidas:payload.config.ts

Dentro de la carpeta Usuarios, tenemos un archivo index.ts básico, que define el tipo de Usuarios. Si bien esto incluye una gran cantidad de Typescript, la mayor parte solo describe el acceso de administrador. Payload permite un control de acceso bastante granular:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import type { CollectionConfig } from 'payload/types' import { admins } from '../../access/admins' import { anyone } from '../../access/anyone' import adminsAndUser from './access/adminsAndUser' import { checkRole } from './checkRole' import { ensureFirstUserIsAdmin } from './hooks/ensureFirstUserIsAdmin' import { loginAfterCreate } from './hooks/loginAfterCreate' const Users: CollectionConfig={ slug: 'users', admin:{ useAsTitle: 'name', defaultColumns: ['name', 'email'], }, access:{ read: adminsAndUser, create: anyone, update: adminsAndUser, delete: admins, admin: ({ req: { user } }) => checkRole(['admin'], user), }, hooks:{ afterChange: [loginAfterCreate], }, auth: true, fields:[ { name: 'name', type: 'text', }, { name: 'roles', type: 'select', hasMany: true, defaultValue: ['user'], options:[ { label: 'admin', value: 'admin', }, { label: 'user', value: 'user', }, ], hooks:{ beforeChange: [ensureFirstUserIsAdmin], }, access:{ read: admins, create: admins, update: admins, }, }, ], timestamps: true, } export default Users |
Sin embargo, vamos a reducir esto y crear nuestro propio tipo de colección, sin administrador ni ganchos.
Digamos que solo queremos un tipo llamado Miembros. Crearé la carpeta adecuada y un index.ts modificado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import type { CollectionConfig } from 'payload/types' const Members: CollectionConfig={ slug: 'members', fields:[ { name: 'name', type: 'text', }, { name: 'membership', type: 'number', }, ], timestamps: true, } export default Members |
Esto simplemente describe un tipo con un nombre y un campo de pertenencia numérico. Payload realiza una gran cantidad de trabajo a través de los diferentes campos.
El servidor detectó los cambios:

E inmediatamente las colecciones reconocieron el nuevo tipo dentro del panel de administración:

Y podemos manipular miembros como cualquier otro tipo de colección:

Una última cosa. Accedamos a nuestro nuevo miembro a través de REST:

Así que estamos bloqueados. Pero espere un minuto... ¿recuerda el acceso granular que eliminamos para simplificar la recopilación de miembros? Intentemos volver a poner un poco de información:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import type { CollectionConfig } from 'payload/types' import { anyone } from '../../access/anyone' const Members: CollectionConfig = { slug: 'members', access: { read: anyone, }, fields: [ { name: 'name', type: 'text', }, { name: 'memebership', type: 'number', }, ], timestamps: true, } export default Members |
Lo único que hice fue agregar la importación para "cualquiera" y agregar ese acceso. Ahora, probemos:

Muy bien. Creamos una nueva colección, la vimos en la consola de administración, creamos una entrada para ella e incluso la solicitamos a través de REST. Por lo tanto, este contenido ahora está disponible para mi sitio.
Conclusión
Como dije antes, Payload está actualmente en transición a la versión 3, por lo que puede tener sentido esperar un poco antes de investigarlo. Dicho esto, la idea ya es bastante sólida si no insistes en que tu frontend y backend se casen a la fuerza.