1653283260
Las API tradicionales se centraron en los servicios REST con puntos finales estándar y verbos HTTP como GET, POST, PUT y DELETE. Con la llegada de GraphQL , REST ahora tiene una alternativa que es igual de sólida y viable para cualquier proyecto.
Hay mucha información disponible sobre cómo trabajar con GraphQL, pero un problema común es conectar su servidor GraphQL a su base de datos. Prisma es una excelente herramienta que simplifica enormemente la interacción con su base de datos a través de una API GraphQL.
Esta publicación cubrirá algunos conceptos básicos sobre GraphQL y luego mostrará cómo usar Prisma con su instancia de GraphQL.
Trabajaremos con un proyecto GraphQL que interactúa con una base de datos de personajes de Star Wars. Este proyecto está disponible en Github aquí . Revisaré esta publicación en una Mac, pero siempre que tenga Bash Shell instalado, los comandos deberían ser los mismos.
Además, si desea tener una forma divertida de buscar personajes de Star Wars para su base de datos, consulte el banco de datos de Star Wars aquí .
GraphQL fue desarrollado originalmente por Facebook en 2012 y consiste en un lenguaje de consulta y manipulación para API. En lugar de crear modelos tradicionales de solicitud/respuesta, GraphQL le permite interactuar con los datos de su aplicación a través de consultas específicas. Estas pueden ser consultas reales, o puede actualizar sus datos usando mutaciones . Esto es particularmente beneficioso cuando le preocupa la eficiencia de sus API y solo recupera lo que es necesario.
Con GraphQL, crea un esquema de datos y resoluciones para controlar qué datos se devuelven y cómo interactúa con ellos. Conectarse a los datos a través de una base de datos puede ser complicado, pero ahí es donde brilla Prisma .
Prisma proporciona un cliente de base de datos para su API GraphQL. Este cliente hace que su vida como desarrollador sea significativamente más fácil porque genera automáticamente los comandos básicos de la base de datos para usted.
La CLI de Prisma incluso activará una base de datos dentro de un contenedor docker con solo unos pocos comandos. Prisma actualmente es compatible con TypeScript, JavaScript, Flow y Go.
En las próximas secciones, crearemos una API de GraphQL que interactúa con una base de datos de personajes de Star Wars. Primero configuraremos la API de GraphQL y luego la conectaremos a una base de datos con Prisma.
Para comenzar, vaya a su terminal y creemos una carpeta e inicialicemos un proyecto con lo siguiente:
mkdir starwars-graphql
cd starwars-graphql
yarn init -y
(NOTA: estamos usando hilo aquí, pero puedes usar npm con la misma facilidad)
Esto solo crea un básico package.json
y luego le permite tener un espacio de trabajo para comenzar a crear su servidor GraphQL.
Ahora vamos a crear un directorio de origen con el index.js
archivo tradicional para su servidor:
mkdir src
touch src/index.js
A continuación, instale el paquete graphql-yoga para automatizar la creación de una instancia completa de GraphQL:
yarn add graphql-yoga
Ahora que tenemos nuestras dependencias, agreguemos lo siguiente:
En su index.js
archivo, continúe y agregue lo siguiente:
const { GraphQLServer } = require('graphql-yoga')
// Type Definition
const typeDefs = `
type Query {
character: String!
}
`
// Resolvers
const resolvers = {
Query: {
character: () => `The force is strong with this API!`
}
}
// Server
const server = new GraphQLServer({
typeDefs,
resolvers,
})
server.start(() => console.log(`Server is running on http://localhost:4000`))
Ahora avancemos y probemos su instancia de GraphQL con lo siguiente:
node src/index.js
Esto debería iniciar su servidor en http://localhost:4000
. Si abre su navegador en ese puerto, debería ver algo como esto:
¿Que es esto? Este es el GraphQL Playground . GraphQL Playground le permite interactuar con su servidor GraphQL localmente. En el panel de la izquierda, puede colocar consultas que interactuarán directamente con sus datos. También puede abrir el esquema a la derecha que muestra los datos que espera este servidor (más sobre eso en un segundo).
A los efectos de nuestra prueba inicial, continúe, copie y pegue lo siguiente en el panel izquierdo y haga clic en la pequeña flecha para ejecutar su primera consulta:
query {
character
}
Una vez que haya ejecutado su consulta, debería ver lo siguiente:
¿Qué hizo esto? ¡Acaba de ejecutar su primera consulta GraphQL!
Ahora veamos el código línea por línea:
// Type Definition
const typeDefs =
`type Query {
character: String!
}`;
La typeDefs
configuración de cómo está interactuando con sus datos, y esto también se conoce como GraphQL Schema . En este caso los datos son muy sencillos, y solo tiene un campo llamado character
que es una cadena. El signo de exclamación ( !
) significa que el character
campo no devolverá un valor nulo.
Un esquema de GraphQL determina el comportamiento de su API y utiliza tipos de raíz especiales . Estos tipos raíz son valores especiales que utiliza GraphQL para determinar cómo interactúa la API con los datos.
Los tres tipos diferentes de raíz comúnmente utilizados son:
NOTA: Para nuestro proyecto, solo vamos a crear una consulta y una mutación. Para obtener más información sobre la suscripción, consulte la publicación del blog de GraphQL aquí .
// Resolvers
const resolvers = {
Query: {
character: () => `The force is strong with this API!`
}
};
resolver
determina cómo se maneja la respuesta a partir de sus definiciones de tipo . En este caso, cada vez que se crea una consulta para character
la cadena "¡la fuerza es fuerte con esta API!" es regresado.
Entonces, para nuestro servidor GraphQL de Star Wars, vamos a interactuar con una base de datos de personajes con los siguientes campos:
Primero cambiemos nuestra typeDefs
sección para reflejar un character
objeto con lo siguiente:
// Type Definition
const typeDefs = `
type Query {
characters: [Character!]!
}
type Character {
name: String!,
species: String!,
affiliation: affiliation!
weapon: String!
}
enum affiliation {
REBEL_ALLIANCE,
EMPIRE
}`;
Nota para obtener más información sobre los tipos y campos de GraphQL, consulte la documentación oficial aquí .
Entonces, ¿qué hizo esto? Vamos sección por sección.
type Query {
characters: [Character!]!
}
Primero, definimos cómo se verá nuestra consulta. Aquí, una consulta con el valor "caracteres" devolverá una matriz de Character
objetos. El signo de exclamación ( !
) indica que el tipo de retorno no será nulo.
type Character {
name: String!,
species: String!,
affiliation: affiliation!
weapon: String!
}
A continuación, definimos nuestro objeto de carácter.
enum affiliation {
REBEL_ALLIANCE,
EMPIRE
}
Finalmente, definimos una enumeración de posibles valores de afiliación (en este caso, la Alianza Rebelde o el Imperio).
Ahora, con las definiciones de Consulta y Objeto configuradas, definamos resolutores para manejar la consulta real.
Reemplace la sección de resolución de arriba con lo siguiente:
// local storage of characters, this will be moved later
const characters = [
{
name: "Han Solo",
species: "Human",
affiliation: "REBEL_ALLIANCE",
weapon: "blaster rifle"
},
{
name: "Chewbacca",
species: "Wookie",
affiliation: "REBEL_ALLIANCE",
weapon: "bowcaster"
}
];
// resolving queries
const resolvers = {
Query: {
characters: () => characters
},
Character: {
name: parent => parent.name,
species: parent => parent.species,
affiliation: parent => parent.affiliation,
weapon: parent => parent.weapon
}
};
¿Qué hizo esto?
// local storage of characters, this will be moved later
const characters = [
{
name: "Han Solo",
species: "Human",
affiliation: "REBEL_ALLIANCE",
weapon: "blaster rifle"
},
{
name: "Chewbacca",
species: "Wookie",
affiliation: "REBEL_ALLIANCE",
weapon: "bowcaster"
}
];
Primero, definimos una versión de almacenamiento local de nuestros personajes. Vamos a recuperarlos directamente de la base de datos una vez que configuremos Prisma. Aquí solo los estamos definiendo en una matriz local para que podamos construir los conceptos básicos de nuestro servidor antes de conectarnos con Prisma.
// resolving queries
const resolvers = {
Query: {
characters: () => characters
},
Character: {
name: parent => parent.name,
species: parent => parent.species,
affiliation: parent => parent.affiliation,
weapon: parent => parent.weapon
}
};
A continuación, definimos un resolver para nuestra consulta para seleccionar los caracteres. ¿Por qué estamos usando parent
aquí? Esto es para que GraphQL pueda resolver la nested
consulta.
Básicamente, primero tuvimos que definir que la Query
operación devolviera una characters
matriz. Usando el parent
campo aquí, estamos diciendo que para cada registro de la characters
matriz, retiremos los campos de caracteres correspondientes.
Ahora continúe y reinicie su servidor con node src/index.js
.
Abra http://localhost:4200
para abrir GraphQL Playground.
Copie la siguiente consulta en el patio de recreo:
query {
characters {
name
species
affiliation
weapon
}
}
Ejecute su consulta y debería ver algo como esto:
Nota: si vio un error sobre campos nulos (o algo por el estilo), solo significa que GraphQL no pudo devolver un valor basado en su consulta. Probablemente solo tenga un error de sintaxis, y recomendaría simplemente consultar el proyecto final de GitHub para asegurarse de que su código coincida.
Si hace clic en el SCHEMA
botón, verá los valores que hemos definido anteriormente. Esta es una excelente manera de validar lo que GraphQL está buscando.
Entonces, solo para repasar, hay tres campos raíz diferentes que se usan comúnmente:
Hasta ahora hemos configurado una consulta que podemos aplicar a una matriz en la memoria. Ahora escribamos una mutación que le permitirá actualizar la matriz de valores y crear un personaje.
Agregue lo siguiente a la typeDefs
sección:
type Mutation {
post(name: String!, species: String!, affiliation: affiliation!, weapon: String!): Character!
}
Esto quiere decir que para a post
con los argumentos asociados (nombre, especie, afiliación y arma), crea un Character
objeto.
A continuación, resolvers
agregue una función para manejar la Mutation
operación con lo siguiente:
Mutation: {
post: (parent, args) => {
const character = {
name: args.name,
species: args.species,
affiliation: args.affiliation,
weapon: args.weapon
};
characters.push(character);
return character;
}
}
Lo que esto dice es que para una mutación , cree un carácter con el args
proporcionado y empújelo a la characters
matriz.
Si va y ejecuta su servidor con node src/index.js
, abra GraphQL IDE en el navegador en localhost:4000
.
En el IDE de GraphQL, ejecute el siguiente comando:
mutation {
post(
name: "Darth Vader"
species: "Human",
affiliation: EMPIRE,
weapon: "lightsaber"
) {
name
}
}
Ahora continúe y ejecute la consulta que creamos antes y debería ver algo como lo siguiente:
Luego, si comenta la mutación y ejecuta la consulta original, debería ver la matriz actualizada con el valor de "Darth Vader" aquí:
¡Felicidades! ¡Ahora tiene una configuración de mutación para su servidor GraphQL!
¿Qué es Prisma ? Como se mencionó en la introducción, Prisma proporciona un cliente que GraphQL puede usar para interactuar con su base de datos.
¿Porque es esto importante? Cuando use GraphQL, querrá conectar su servidor a una base de datos real. El acceso a la base de datos requiere la creación de consultas SQL directas o el uso de un Mapeo relacional de objetos (ORM) tradicional para interactuar con la base de datos. Las consultas SQL son propensas a errores, ya que deben enviarse como cadenas. Los ORM suelen ser muy simples y difíciles de escalar para que funcionen correctamente con aplicaciones complejas.
…entra Prisma
Prisma se encarga del desafío de conectar su servidor a su base de datos a través de (1) un cliente generado y (2) un servidor que traduce sus llamadas GraphQL en comandos para su base de datos.
El flujo resultante debería parecerse al siguiente:
El cliente generado se convierte en parte de su servidor GraphQL y sirve como medio para traducir sus consultas, mutaciones y suscripciones en llamadas a la base de datos.
Prisma tiene una CLI que hace que todo este proceso sea muy fácil. Para nuestro proyecto, vamos a utilizar la CLI de Prisma para crear una base de datos de demostración alojada con AWS Aurora DB .
¡Entonces empecemos!
Primero, creemos un directorio Prisma en el proyecto:
mkdir prisma
touch prisma/prisma.yml
touch prisma/datamodel.prisma
Abra el datamodel.prisma
archivo y agregue lo siguiente:
type Character {
id: ID! @id
name: String!
species: String!
affiliation: affiliation!
weapon: String!
}
enum affiliation {
REBEL_ALLIANCE
EMPIRE
}
Esto define el Character
objeto para Prisma. Si nota que creamos el @id
valor aquí, esto es para que cada registro creado con Prisma sea único. Prisma generará automáticamente el valor de ID para nosotros, con cada nuevo registro.
A continuación, abra el prisma.yml
archivo y agregue lo siguiente:
# HTTP Endpoint
endpoint: ""
# location of the datamodel file
datamodel: datamodel.prisma
# identifiy the language and location of the Prisma Client
generate:
- generator: javascript-client
output: ../src/generated/prisma-client
Este archivo hace lo siguiente:
deploy
comando)datamodel
archivoAhora estamos listos para construir el cliente, así que instalemos la CLI de Prisma globalmente con:
yarn global add prisma
Una vez que se complete, necesitaremos generar el código Prisma Client. Cualquiera de los comandos con Prisma CLI tiene el prefijo prisma
, y dará como resultado que responda las indicaciones con información sobre el tipo de base de datos, la ubicación, etc.
En su terminal, vaya a la raíz del proyecto y ejecute lo siguiente:
prisma deploy
En su terminal, seleccione "Servidor de demostración + base de datos MySQL" para permitir que Prisma le construya una demostración en la nube (es gratis). Su terminal debe ser similar a lo siguiente:
Ahora, con la infraestructura implementada en la nube, puede generar el Prisma Client que utilizará su API de GraphQL ejecutando lo siguiente (en la raíz del proyecto):prisma generate
.
Ahora Prisma Client está configurado y su Prisma Server está implementado.
Para poder trabajar con nuestro Cliente Prisma, necesitaremos instalar el prisma-client-lib
paquete con:yarn add prisma-client-lib
Una vez que haya instalado la biblioteca del cliente, puede probar la creación de un registro en la instancia de su base de datos ejecutando lo siguiente (guardado en el proyecto de muestra como prisma_client.js
):
const { prisma } = require("./generated/prisma-client");
async function main() {
// Create a new character
const newCharacter = await prisma.createCharacter({
name: "Luke Skywalker",
species: "Human",
affiliation: "REBEL_ALLIANCE",
weapon: "lightsaber"
});
console.log(
`Created new character: ${newCharacter.name} (ID: ${newCharacter.id})`
);
const allCharacters = await prisma.characters();
console.log(allCharacters);
}
main().catch(e => console.error(e));
Una vez que haya ejecutado este código, también puede verlo en Prisma Console si va a https://app.prisma.io/ .
Ejecutar prisma_client.js
debería dar como resultado algo como lo siguiente:
Luego, si va a su navegador en https://app.prisma.io/ , puede ver directamente los datos con los que estábamos trabajando:
¡Felicitaciones por obtener la configuración del cliente! 🎉
Entonces, el último paso es conectar nuestro servidor GraphQL a nuestro Cliente generado. El prisma_client.js
archivo es un archivo independiente que se ejecuta para agregar valores directamente a la base de datos. Queremos usar la consulta y la mutación que creamos antes para interactuar directamente con nuestra base de datos.
Primero, abra nuestro archivo de servidor en src/index.js
y agregue una línea para extraer Prisma Client.const { prisma } = require("./generated/prisma-client");
Luego, en la parte inferior del archivo del servidor, redefinamos nuestra instancia de servidor con lo siguiente:
// Server
const server = new GraphQLServer({
typeDefs,
resolvers,
context: { prisma }
});
server.start(() => console.log(`Server is running on http://localhost:4000`));
Si nota que aquí estamos definiendo un context
objeto que es esencialmente nuestro Cliente Prisma. No teníamos esto antes porque solo lo estábamos ejecutando en la memoria. Definir context
aquí como nuestro Cliente Prisma permite que todas las solicitudes usen la misma conexión a nuestro servidor Prisma y recuperó la base de datos. Para obtener más información sobre los context
objetos en GraphQL, consulte la documentación aquí .
Finalmente, cambiemos nuestros resolutores en el src/index.js
archivo para que sean los siguientes:
// // local storage of characters, this will be moved later
// const characters = [
// {
// name: "Han Solo",
// species: "Human",
// affiliation: "REBEL_ALLIANCE",
// weapon: "blaster rifle"
// },
// {
// name: "Chewbacca",
// species: "Wookie",
// affiliation: "REBEL_ALLIANCE",
// weapon: "bowcaster"
// }
// ];
// resolving queries
const resolvers = {
Query: {
characters: (root, args, context, info) => {
return context.prisma.characters();
}
},
Mutation: {
post: (root, args, context) => {
return context.prisma.createCharacter({
name: args.name,
species: args.species,
affiliation: args.affiliation,
weapon: args.weapon
});
}
}
};
¿Qué está haciendo esto? Esto modificó la consulta y la mutación para apuntar al Prisma Client y al servidor en lugar de nuestra matriz local. Además, comenta nuestra matriz de caracteres como ves aquí, ya que no los necesitaremos ahora.
Entonces, ahora que todo está configurado, sigamos adelante y reiniciemos nuestro servidor node src/index.js
y luego abramos GraphQL Playground en https://localhost:4000 .
Ejecute la siguiente mutación para escribir un valor en nuestra base de datos:
mutation {
post(
name: "Leia Organa"
species: "Human",
affiliation: REBEL_ALLIANCE,
weapon: "blastor pistol"
) {
name
}
}
Deberías ver lo siguiente:
Luego ejecute la consulta para ver que Leia está en nuestra base de datos:
NOTA: Agregué algunos de los personajes durante la prueba, por lo que es posible que tenga resultados ligeramente diferentes aquí. Lo importante es que Leia está en la lista.
Y también puede abrir el sitio de Prisma Client para ver el registro poblado en su base de datos:
¡Ya ha conectado nuestro servidor GraphQL a la base de datos!
NOTA: En este punto, también podría refactorizar la aplicación. Por lo general, las aplicaciones más grandes tienen lugares para un resolvers
archivo y un definitions
archivo (en lugar de definirlos todos en un solo lugar). Aquí nuestra API era realmente simple, así que dejé el archivo como está.
Entonces, con esta publicación, aprendimos algunos conceptos básicos sobre GraphQL y también cómo usar la poderosa herramienta Prisma. Construimos una consulta y una mutación de un servidor GraphQL. También aprendimos sobre GraphQL Playground. Espero que esta publicación le haya ayudado a comenzar con GraphQL y le haya ayudado a familiarizarse con el desarrollo.
GraphQL es una tecnología realmente poderosa que hace que las aplicaciones sean eficientes y fáciles de usar. Prisma también es una herramienta muy útil que simplifica enormemente la creación de sus aplicaciones GraphQL.
Los siguientes pasos de este proyecto serían considerar implementar su instancia de servidor GraphQL y construir un cliente front-end que pueda llamar a su API.
Prisma también tiene muchas características que no cubrimos aquí. Recomiendo encarecidamente visitar su sitio web y ver sus ejemplos.
Fuente: https://blog.logrocket.com/intro-to-graphql-with-prisma/
1653283260
Las API tradicionales se centraron en los servicios REST con puntos finales estándar y verbos HTTP como GET, POST, PUT y DELETE. Con la llegada de GraphQL , REST ahora tiene una alternativa que es igual de sólida y viable para cualquier proyecto.
Hay mucha información disponible sobre cómo trabajar con GraphQL, pero un problema común es conectar su servidor GraphQL a su base de datos. Prisma es una excelente herramienta que simplifica enormemente la interacción con su base de datos a través de una API GraphQL.
Esta publicación cubrirá algunos conceptos básicos sobre GraphQL y luego mostrará cómo usar Prisma con su instancia de GraphQL.
Trabajaremos con un proyecto GraphQL que interactúa con una base de datos de personajes de Star Wars. Este proyecto está disponible en Github aquí . Revisaré esta publicación en una Mac, pero siempre que tenga Bash Shell instalado, los comandos deberían ser los mismos.
Además, si desea tener una forma divertida de buscar personajes de Star Wars para su base de datos, consulte el banco de datos de Star Wars aquí .
GraphQL fue desarrollado originalmente por Facebook en 2012 y consiste en un lenguaje de consulta y manipulación para API. En lugar de crear modelos tradicionales de solicitud/respuesta, GraphQL le permite interactuar con los datos de su aplicación a través de consultas específicas. Estas pueden ser consultas reales, o puede actualizar sus datos usando mutaciones . Esto es particularmente beneficioso cuando le preocupa la eficiencia de sus API y solo recupera lo que es necesario.
Con GraphQL, crea un esquema de datos y resoluciones para controlar qué datos se devuelven y cómo interactúa con ellos. Conectarse a los datos a través de una base de datos puede ser complicado, pero ahí es donde brilla Prisma .
Prisma proporciona un cliente de base de datos para su API GraphQL. Este cliente hace que su vida como desarrollador sea significativamente más fácil porque genera automáticamente los comandos básicos de la base de datos para usted.
La CLI de Prisma incluso activará una base de datos dentro de un contenedor docker con solo unos pocos comandos. Prisma actualmente es compatible con TypeScript, JavaScript, Flow y Go.
En las próximas secciones, crearemos una API de GraphQL que interactúa con una base de datos de personajes de Star Wars. Primero configuraremos la API de GraphQL y luego la conectaremos a una base de datos con Prisma.
Para comenzar, vaya a su terminal y creemos una carpeta e inicialicemos un proyecto con lo siguiente:
mkdir starwars-graphql
cd starwars-graphql
yarn init -y
(NOTA: estamos usando hilo aquí, pero puedes usar npm con la misma facilidad)
Esto solo crea un básico package.json
y luego le permite tener un espacio de trabajo para comenzar a crear su servidor GraphQL.
Ahora vamos a crear un directorio de origen con el index.js
archivo tradicional para su servidor:
mkdir src
touch src/index.js
A continuación, instale el paquete graphql-yoga para automatizar la creación de una instancia completa de GraphQL:
yarn add graphql-yoga
Ahora que tenemos nuestras dependencias, agreguemos lo siguiente:
En su index.js
archivo, continúe y agregue lo siguiente:
const { GraphQLServer } = require('graphql-yoga')
// Type Definition
const typeDefs = `
type Query {
character: String!
}
`
// Resolvers
const resolvers = {
Query: {
character: () => `The force is strong with this API!`
}
}
// Server
const server = new GraphQLServer({
typeDefs,
resolvers,
})
server.start(() => console.log(`Server is running on http://localhost:4000`))
Ahora avancemos y probemos su instancia de GraphQL con lo siguiente:
node src/index.js
Esto debería iniciar su servidor en http://localhost:4000
. Si abre su navegador en ese puerto, debería ver algo como esto:
¿Que es esto? Este es el GraphQL Playground . GraphQL Playground le permite interactuar con su servidor GraphQL localmente. En el panel de la izquierda, puede colocar consultas que interactuarán directamente con sus datos. También puede abrir el esquema a la derecha que muestra los datos que espera este servidor (más sobre eso en un segundo).
A los efectos de nuestra prueba inicial, continúe, copie y pegue lo siguiente en el panel izquierdo y haga clic en la pequeña flecha para ejecutar su primera consulta:
query {
character
}
Una vez que haya ejecutado su consulta, debería ver lo siguiente:
¿Qué hizo esto? ¡Acaba de ejecutar su primera consulta GraphQL!
Ahora veamos el código línea por línea:
// Type Definition
const typeDefs =
`type Query {
character: String!
}`;
La typeDefs
configuración de cómo está interactuando con sus datos, y esto también se conoce como GraphQL Schema . En este caso los datos son muy sencillos, y solo tiene un campo llamado character
que es una cadena. El signo de exclamación ( !
) significa que el character
campo no devolverá un valor nulo.
Un esquema de GraphQL determina el comportamiento de su API y utiliza tipos de raíz especiales . Estos tipos raíz son valores especiales que utiliza GraphQL para determinar cómo interactúa la API con los datos.
Los tres tipos diferentes de raíz comúnmente utilizados son:
NOTA: Para nuestro proyecto, solo vamos a crear una consulta y una mutación. Para obtener más información sobre la suscripción, consulte la publicación del blog de GraphQL aquí .
// Resolvers
const resolvers = {
Query: {
character: () => `The force is strong with this API!`
}
};
resolver
determina cómo se maneja la respuesta a partir de sus definiciones de tipo . En este caso, cada vez que se crea una consulta para character
la cadena "¡la fuerza es fuerte con esta API!" es regresado.
Entonces, para nuestro servidor GraphQL de Star Wars, vamos a interactuar con una base de datos de personajes con los siguientes campos:
Primero cambiemos nuestra typeDefs
sección para reflejar un character
objeto con lo siguiente:
// Type Definition
const typeDefs = `
type Query {
characters: [Character!]!
}
type Character {
name: String!,
species: String!,
affiliation: affiliation!
weapon: String!
}
enum affiliation {
REBEL_ALLIANCE,
EMPIRE
}`;
Nota para obtener más información sobre los tipos y campos de GraphQL, consulte la documentación oficial aquí .
Entonces, ¿qué hizo esto? Vamos sección por sección.
type Query {
characters: [Character!]!
}
Primero, definimos cómo se verá nuestra consulta. Aquí, una consulta con el valor "caracteres" devolverá una matriz de Character
objetos. El signo de exclamación ( !
) indica que el tipo de retorno no será nulo.
type Character {
name: String!,
species: String!,
affiliation: affiliation!
weapon: String!
}
A continuación, definimos nuestro objeto de carácter.
enum affiliation {
REBEL_ALLIANCE,
EMPIRE
}
Finalmente, definimos una enumeración de posibles valores de afiliación (en este caso, la Alianza Rebelde o el Imperio).
Ahora, con las definiciones de Consulta y Objeto configuradas, definamos resolutores para manejar la consulta real.
Reemplace la sección de resolución de arriba con lo siguiente:
// local storage of characters, this will be moved later
const characters = [
{
name: "Han Solo",
species: "Human",
affiliation: "REBEL_ALLIANCE",
weapon: "blaster rifle"
},
{
name: "Chewbacca",
species: "Wookie",
affiliation: "REBEL_ALLIANCE",
weapon: "bowcaster"
}
];
// resolving queries
const resolvers = {
Query: {
characters: () => characters
},
Character: {
name: parent => parent.name,
species: parent => parent.species,
affiliation: parent => parent.affiliation,
weapon: parent => parent.weapon
}
};
¿Qué hizo esto?
// local storage of characters, this will be moved later
const characters = [
{
name: "Han Solo",
species: "Human",
affiliation: "REBEL_ALLIANCE",
weapon: "blaster rifle"
},
{
name: "Chewbacca",
species: "Wookie",
affiliation: "REBEL_ALLIANCE",
weapon: "bowcaster"
}
];
Primero, definimos una versión de almacenamiento local de nuestros personajes. Vamos a recuperarlos directamente de la base de datos una vez que configuremos Prisma. Aquí solo los estamos definiendo en una matriz local para que podamos construir los conceptos básicos de nuestro servidor antes de conectarnos con Prisma.
// resolving queries
const resolvers = {
Query: {
characters: () => characters
},
Character: {
name: parent => parent.name,
species: parent => parent.species,
affiliation: parent => parent.affiliation,
weapon: parent => parent.weapon
}
};
A continuación, definimos un resolver para nuestra consulta para seleccionar los caracteres. ¿Por qué estamos usando parent
aquí? Esto es para que GraphQL pueda resolver la nested
consulta.
Básicamente, primero tuvimos que definir que la Query
operación devolviera una characters
matriz. Usando el parent
campo aquí, estamos diciendo que para cada registro de la characters
matriz, retiremos los campos de caracteres correspondientes.
Ahora continúe y reinicie su servidor con node src/index.js
.
Abra http://localhost:4200
para abrir GraphQL Playground.
Copie la siguiente consulta en el patio de recreo:
query {
characters {
name
species
affiliation
weapon
}
}
Ejecute su consulta y debería ver algo como esto:
Nota: si vio un error sobre campos nulos (o algo por el estilo), solo significa que GraphQL no pudo devolver un valor basado en su consulta. Probablemente solo tenga un error de sintaxis, y recomendaría simplemente consultar el proyecto final de GitHub para asegurarse de que su código coincida.
Si hace clic en el SCHEMA
botón, verá los valores que hemos definido anteriormente. Esta es una excelente manera de validar lo que GraphQL está buscando.
Entonces, solo para repasar, hay tres campos raíz diferentes que se usan comúnmente:
Hasta ahora hemos configurado una consulta que podemos aplicar a una matriz en la memoria. Ahora escribamos una mutación que le permitirá actualizar la matriz de valores y crear un personaje.
Agregue lo siguiente a la typeDefs
sección:
type Mutation {
post(name: String!, species: String!, affiliation: affiliation!, weapon: String!): Character!
}
Esto quiere decir que para a post
con los argumentos asociados (nombre, especie, afiliación y arma), crea un Character
objeto.
A continuación, resolvers
agregue una función para manejar la Mutation
operación con lo siguiente:
Mutation: {
post: (parent, args) => {
const character = {
name: args.name,
species: args.species,
affiliation: args.affiliation,
weapon: args.weapon
};
characters.push(character);
return character;
}
}
Lo que esto dice es que para una mutación , cree un carácter con el args
proporcionado y empújelo a la characters
matriz.
Si va y ejecuta su servidor con node src/index.js
, abra GraphQL IDE en el navegador en localhost:4000
.
En el IDE de GraphQL, ejecute el siguiente comando:
mutation {
post(
name: "Darth Vader"
species: "Human",
affiliation: EMPIRE,
weapon: "lightsaber"
) {
name
}
}
Ahora continúe y ejecute la consulta que creamos antes y debería ver algo como lo siguiente:
Luego, si comenta la mutación y ejecuta la consulta original, debería ver la matriz actualizada con el valor de "Darth Vader" aquí:
¡Felicidades! ¡Ahora tiene una configuración de mutación para su servidor GraphQL!
¿Qué es Prisma ? Como se mencionó en la introducción, Prisma proporciona un cliente que GraphQL puede usar para interactuar con su base de datos.
¿Porque es esto importante? Cuando use GraphQL, querrá conectar su servidor a una base de datos real. El acceso a la base de datos requiere la creación de consultas SQL directas o el uso de un Mapeo relacional de objetos (ORM) tradicional para interactuar con la base de datos. Las consultas SQL son propensas a errores, ya que deben enviarse como cadenas. Los ORM suelen ser muy simples y difíciles de escalar para que funcionen correctamente con aplicaciones complejas.
…entra Prisma
Prisma se encarga del desafío de conectar su servidor a su base de datos a través de (1) un cliente generado y (2) un servidor que traduce sus llamadas GraphQL en comandos para su base de datos.
El flujo resultante debería parecerse al siguiente:
El cliente generado se convierte en parte de su servidor GraphQL y sirve como medio para traducir sus consultas, mutaciones y suscripciones en llamadas a la base de datos.
Prisma tiene una CLI que hace que todo este proceso sea muy fácil. Para nuestro proyecto, vamos a utilizar la CLI de Prisma para crear una base de datos de demostración alojada con AWS Aurora DB .
¡Entonces empecemos!
Primero, creemos un directorio Prisma en el proyecto:
mkdir prisma
touch prisma/prisma.yml
touch prisma/datamodel.prisma
Abra el datamodel.prisma
archivo y agregue lo siguiente:
type Character {
id: ID! @id
name: String!
species: String!
affiliation: affiliation!
weapon: String!
}
enum affiliation {
REBEL_ALLIANCE
EMPIRE
}
Esto define el Character
objeto para Prisma. Si nota que creamos el @id
valor aquí, esto es para que cada registro creado con Prisma sea único. Prisma generará automáticamente el valor de ID para nosotros, con cada nuevo registro.
A continuación, abra el prisma.yml
archivo y agregue lo siguiente:
# HTTP Endpoint
endpoint: ""
# location of the datamodel file
datamodel: datamodel.prisma
# identifiy the language and location of the Prisma Client
generate:
- generator: javascript-client
output: ../src/generated/prisma-client
Este archivo hace lo siguiente:
deploy
comando)datamodel
archivoAhora estamos listos para construir el cliente, así que instalemos la CLI de Prisma globalmente con:
yarn global add prisma
Una vez que se complete, necesitaremos generar el código Prisma Client. Cualquiera de los comandos con Prisma CLI tiene el prefijo prisma
, y dará como resultado que responda las indicaciones con información sobre el tipo de base de datos, la ubicación, etc.
En su terminal, vaya a la raíz del proyecto y ejecute lo siguiente:
prisma deploy
En su terminal, seleccione "Servidor de demostración + base de datos MySQL" para permitir que Prisma le construya una demostración en la nube (es gratis). Su terminal debe ser similar a lo siguiente:
Ahora, con la infraestructura implementada en la nube, puede generar el Prisma Client que utilizará su API de GraphQL ejecutando lo siguiente (en la raíz del proyecto):prisma generate
.
Ahora Prisma Client está configurado y su Prisma Server está implementado.
Para poder trabajar con nuestro Cliente Prisma, necesitaremos instalar el prisma-client-lib
paquete con:yarn add prisma-client-lib
Una vez que haya instalado la biblioteca del cliente, puede probar la creación de un registro en la instancia de su base de datos ejecutando lo siguiente (guardado en el proyecto de muestra como prisma_client.js
):
const { prisma } = require("./generated/prisma-client");
async function main() {
// Create a new character
const newCharacter = await prisma.createCharacter({
name: "Luke Skywalker",
species: "Human",
affiliation: "REBEL_ALLIANCE",
weapon: "lightsaber"
});
console.log(
`Created new character: ${newCharacter.name} (ID: ${newCharacter.id})`
);
const allCharacters = await prisma.characters();
console.log(allCharacters);
}
main().catch(e => console.error(e));
Una vez que haya ejecutado este código, también puede verlo en Prisma Console si va a https://app.prisma.io/ .
Ejecutar prisma_client.js
debería dar como resultado algo como lo siguiente:
Luego, si va a su navegador en https://app.prisma.io/ , puede ver directamente los datos con los que estábamos trabajando:
¡Felicitaciones por obtener la configuración del cliente! 🎉
Entonces, el último paso es conectar nuestro servidor GraphQL a nuestro Cliente generado. El prisma_client.js
archivo es un archivo independiente que se ejecuta para agregar valores directamente a la base de datos. Queremos usar la consulta y la mutación que creamos antes para interactuar directamente con nuestra base de datos.
Primero, abra nuestro archivo de servidor en src/index.js
y agregue una línea para extraer Prisma Client.const { prisma } = require("./generated/prisma-client");
Luego, en la parte inferior del archivo del servidor, redefinamos nuestra instancia de servidor con lo siguiente:
// Server
const server = new GraphQLServer({
typeDefs,
resolvers,
context: { prisma }
});
server.start(() => console.log(`Server is running on http://localhost:4000`));
Si nota que aquí estamos definiendo un context
objeto que es esencialmente nuestro Cliente Prisma. No teníamos esto antes porque solo lo estábamos ejecutando en la memoria. Definir context
aquí como nuestro Cliente Prisma permite que todas las solicitudes usen la misma conexión a nuestro servidor Prisma y recuperó la base de datos. Para obtener más información sobre los context
objetos en GraphQL, consulte la documentación aquí .
Finalmente, cambiemos nuestros resolutores en el src/index.js
archivo para que sean los siguientes:
// // local storage of characters, this will be moved later
// const characters = [
// {
// name: "Han Solo",
// species: "Human",
// affiliation: "REBEL_ALLIANCE",
// weapon: "blaster rifle"
// },
// {
// name: "Chewbacca",
// species: "Wookie",
// affiliation: "REBEL_ALLIANCE",
// weapon: "bowcaster"
// }
// ];
// resolving queries
const resolvers = {
Query: {
characters: (root, args, context, info) => {
return context.prisma.characters();
}
},
Mutation: {
post: (root, args, context) => {
return context.prisma.createCharacter({
name: args.name,
species: args.species,
affiliation: args.affiliation,
weapon: args.weapon
});
}
}
};
¿Qué está haciendo esto? Esto modificó la consulta y la mutación para apuntar al Prisma Client y al servidor en lugar de nuestra matriz local. Además, comenta nuestra matriz de caracteres como ves aquí, ya que no los necesitaremos ahora.
Entonces, ahora que todo está configurado, sigamos adelante y reiniciemos nuestro servidor node src/index.js
y luego abramos GraphQL Playground en https://localhost:4000 .
Ejecute la siguiente mutación para escribir un valor en nuestra base de datos:
mutation {
post(
name: "Leia Organa"
species: "Human",
affiliation: REBEL_ALLIANCE,
weapon: "blastor pistol"
) {
name
}
}
Deberías ver lo siguiente:
Luego ejecute la consulta para ver que Leia está en nuestra base de datos:
NOTA: Agregué algunos de los personajes durante la prueba, por lo que es posible que tenga resultados ligeramente diferentes aquí. Lo importante es que Leia está en la lista.
Y también puede abrir el sitio de Prisma Client para ver el registro poblado en su base de datos:
¡Ya ha conectado nuestro servidor GraphQL a la base de datos!
NOTA: En este punto, también podría refactorizar la aplicación. Por lo general, las aplicaciones más grandes tienen lugares para un resolvers
archivo y un definitions
archivo (en lugar de definirlos todos en un solo lugar). Aquí nuestra API era realmente simple, así que dejé el archivo como está.
Entonces, con esta publicación, aprendimos algunos conceptos básicos sobre GraphQL y también cómo usar la poderosa herramienta Prisma. Construimos una consulta y una mutación de un servidor GraphQL. También aprendimos sobre GraphQL Playground. Espero que esta publicación le haya ayudado a comenzar con GraphQL y le haya ayudado a familiarizarse con el desarrollo.
GraphQL es una tecnología realmente poderosa que hace que las aplicaciones sean eficientes y fáciles de usar. Prisma también es una herramienta muy útil que simplifica enormemente la creación de sus aplicaciones GraphQL.
Los siguientes pasos de este proyecto serían considerar implementar su instancia de servidor GraphQL y construir un cliente front-end que pueda llamar a su API.
Prisma también tiene muchas características que no cubrimos aquí. Recomiendo encarecidamente visitar su sitio web y ver sus ejemplos.
Fuente: https://blog.logrocket.com/intro-to-graphql-with-prisma/
1651813200
Why use this package over the other available Elm GraphQL packages? This is the only one that generates type-safe code for your entire schema. Check out this blog post, Type-Safe & Composable GraphQL in Elm, to learn more about the motivation for this library. (It's also the only type-safe library with Elm 0.18 or 0.19 support, see this discourse thread).
I built this package because I wanted to have something that:
See an example in action on Ellie. See more end-to-end example code in the examples/
folder.
dillonkearns/elm-graphql
is an Elm package and accompanying command-line code generator that creates type-safe Elm code for your GraphQL endpoint. You don't write any decoders for your API with dillonkearns/elm-graphql
, instead you simply select which fields you would like, similar to a standard GraphQL query but in Elm. For example, this GraphQL query
query {
human(id: "1001") {
name
homePlanet
}
}
would look like this in dillonkearns/elm-graphql
(the code in this example that is prefixed with StarWars
is auto-generated)
import Graphql.Operation exposing (RootQuery)
import Graphql.SelectionSet as SelectionSet exposing (SelectionSet)
import StarWars.Object
import StarWars.Object.Human as Human
import StarWars.Query as Query
import StarWars.Scalar exposing (Id(..))
query : SelectionSet (Maybe HumanData) RootQuery
query =
Query.human { id = Id "1001" } humanSelection
type alias HumanData =
{ name : String
, homePlanet : Maybe String
}
humanSelection : SelectionSet HumanData StarWars.Object.Human
humanSelection =
SelectionSet.map2 HumanData
Human.name
Human.homePlanet
GraphQL and Elm are a perfect match because GraphQL is used to enforce the types that your API takes as inputs and outputs, much like Elm's type system does within Elm. elm-graphql
simply bridges this gap by making your Elm code aware of your GraphQL server's schema. If you are new to GraphQL, graphql.org/learn/ is an excellent way to learn the basics.
After following the installation instructions to install the @dillonkearns/elm-graphql
NPM package and the proper Elm packages (see the Setup section for details). Once you've installed everything, running the elm-graphql
code generation tool is as simple as this:
npx elm-graphql https://elm-graphql.herokuapp.com --base StarWars --output examples/src
If headers are required, such as a Bearer Token, the --header
flag can be supplied.
npx elm-graphql https://elm-graphql.herokuapp.com --base StarWars --output examples/src --header 'headerKey: header value'
There is a thorough tutorial in the SelectionSet
docs. SelectionSet
s are the core concept in this library, so I recommend reading through the whole page (it's not very long!).
The examples/
folder is another great place to start.
If you want to learn more GraphQL basics, this is a great tutorial, and a short read: graphql.org/learn/
My Elm Conf 2018 talk goes into the philosophy behind dillonkearns/elm-graphql
(Skip to 13:06 to go straight to the dillonkearns/elm-graphql
demo).
elm-graphql
using the Scalar Codecs feature. If you're wondering why code is generated a certain way, you're likely to find an answer in the Frequently Asked Questions (FAQ).
There's a very helpful group of people in the #graphql channel in the Elm Slack. Don't hesitate to ask any questions about getting started, best practices, or just general GraphQL in there!
dillonkearns/elm-graphql
generates Elm code that allows you to build up type-safe GraphQL requests. Here are the steps to setup dillonkearns/elm-graphql
.
Add the dillonkearns/elm-graphql
elm package as a dependency in your elm.json
. You will also need to make sure that elm/json
is a dependency of your project since the generated code has lots of JSON decoders in it.
elm install dillonkearns/elm-graphql
elm install elm/json
Install the @dillonkearns/elm-graphql
command line tool through npm. This is what you will use to generate Elm code for your API. It is recommended that you save the @dillonkearns/elm-graphql
command line tool as a dev dependency so that everyone on your project is using the same version.
npm install --save-dev @dillonkearns/elm-graphql
# you can now run it locally using `npx elm-graphql`,
# or by calling it through an npm script as in this project's package.json
Run the @dillonkearns/elm-graphql
command line tool installed above to generate your code. If you used the --save-dev
method above, you can simply create a script in your package.json like the following:
{
"name": "star-wars-elm-graphql-project",
"version": "1.0.0",
"scripts": {
"api": "elm-graphql https://elm-graphql.herokuapp.com/api --base StarWars"
}
With the above in your package.json
, running npm run api
will generate dillonkearns/elm-graphql
code for you to call in ./src/StarWars/
. You can now use the generated code as in this Ellie example or in the examples
folder.
You can do real-time APIs using GraphQL Subscriptions and dillonkearns/elm-graphql
. Just wire in the framework-specific JavaScript code for opening the WebSocket connection through a port. Here's a live demo and its source code. The demo server is running Elixir/Absinthe.
Thank you Mario Martinez (martimatix) for all your feedback, the elm-format PR, and for the incredible logo design!
Thank you Mike Stock (mikeastock) for setting up Travis CI!
Thanks for the reserved words pull request @madsflensted!
A huge thanks to @xtian for doing the vast majority of the 0.19 upgrade work! :tada:
Thank you Josh Adams (@knewter) for the code example for Subscriptions with Elixir/Absinthe wired up through Elm ports!
Thank you Romario for adding OptionalArgument.map
!
Thank you Aaron White for your pull request to improve the performance and stability of the elm-format
step! 🎉
All core features are supported. That is, you can build any query or mutation with your dillonkearns/elm-graphql
-generated code, and it is guaranteed to be valid according to your server's schema.
dillonkearns/elm-graphql
will generate code for you to generate subscriptions and decode the responses, but it doesn't deal with the low-level details for how to send them over web sockets. To do that, you will need to use custom code or a package that knows how to communicate over websockets (or whichever protocol) to setup a subscription with your particular framework. See this discussion for why those details are not handled by this library directly.
I would love to hear feedback if you are using GraphQL Subscriptions. In particular, I'd love to see live code examples to drive any improvements to the Subscriptions design. Please ping me on Slack, drop a message in the #graphql channel, or open up a Github issue to discuss!
I would like to investigate generating helpers to make pagination simpler for Connections (based on the Relay Cursor Connections Specification). If you have ideas on this chime in on this thread.
See the full roadmap on Trello.
Author: dillonkearns
Source Code: https://github.com/dillonkearns/elm-graphql
License: View license
1636390800
In this article, you will create the GraphQL API and interact with it on the frontend.
#graphql #api #typescript #postgresql #nextjs #prisma #graphql
1636383600
In this article, we'll create the data model and explore the different components of Prisma.
1646981340
This repository contains a number of ready-to-run example projects demonstrating various use cases of Prisma. Pick an example and follow the instructions in the corresponding README.
You can also find links to real-world and production ready examples further below in this README.
Are you missing an example? Please feel free to open an issue (read the contribution guidelines for more info).
Demo | Description |
---|---|
rest-nextjs-api-routes | Next.js app with a REST API (using Next.js API routes) |
rest-nextjs-api-routes-auth | Next.js app with a REST API (using Next.js API routes) and authentication (using NextAuth.js) |
rest-nextjs-express | Next.js app with a REST API (using Express) |
graphql-nextjs | Next.js app with a GraphQL API (using Apollo Server and GraphQL Nexus) |
Demo | Description |
---|---|
graphql-apollo-server | GraphQL server based on apollo-server and Nexus Schema |
graphql-auth | GraphQL server with email-password authentication & permissions |
graphql-sdl-first | GraphQL server based on the SDL-first approach of graphql-tools |
graphql-subscriptions | GraphQL server with realtime subscriptions based on apollo-server and Nexus Schema |
graphql-typegraphql | GraphQL server based on apollo-server and TypeGraphQL |
graphql-typegraphql-crud | CRUD GraphQL API based on apollo-server and TypeGraphQL |
graphql-express | GraphQL server based on Express and Nexus Schema |
graphql-express-sdl-first | GraphQL server based on Express and the SDL-first approach of graphql-tools |
graphql-fastify | GraphQL server based on Fastify, Mercurius, and the SDL-first approach of graphql-tools |
graphql-fastify-sdl-first | GraphQL server based on Fastify, Mercurius, and the SDL-first approach of graphql-tools |
graphql-hapi | GraphQL server based on Hapi and Nexus Schema |
graphql-hapi-sdl-first | GraphQL server based on Hapi and the SDL-first approach of Apollo Server Hapi |
graphql-nestjs | GraphQL server based on NestJS (code-first) |
graphql-nestjs-sdl-first | GraphQL server based on NestJS and the SDL-first approach of graphql-tools |
graphql | GraphQL server based on apollo-server and Nexus Schema |
grpc | gRPC API including runnable client scripts for testing |
postgis-express | Demo of spatial queries using Postgis and Express |
rest-express | REST API with Express |
rest-fastify | REST API with Fastify |
rest-hapi | REST API with hapi |
rest-nestjs | REST API with NestJS |
script | Usage of Prisma Client JS in a TypeScript script |
testing-express | Demo of integration tests with Jest, Supertest and Express |
Demo | Description |
---|---|
rest-nextjs | Next.js app with a REST API (using Next.js API routes) |
rest-nuxtjs | NuxtJS app with a REST API |
Demo | Description |
---|---|
graphql-apollo-server | GraphQL server based on apollo-server |
graphql-auth | GraphQL server with email-password authentication & permissions |
graphql-sdl-first | GraphQL server based on the SDL-first approach of graphql-tools |
grpc | gRPC API including runnable client scripts for testing |
rest-express | REST API with Express |
rest-fastify | REST API with Fastify |
script | Usage of Prisma Client JS in a Node.js script |
The projects in the deployment-platforms
directory show what "Prisma Client"-based deployment setups look like for various deployment providers. Learn more about deployment in the Prisma documentation.
The latest
branch of this repository contains the examples with the latest stable version of Prisma CLI and Prisma Client (@latest
on npm). These dependencies are kept up to date with a GitHub Action workflow, which updates them every time a new version of Prisma is released.
There are also the automated branches dev
and patch-dev
, which mirror the code from latest
(synced via a GitHub Action workflow), but they use the respective development channels of Prisma CLI and Prisma Client from npm instead (@dev
and @patch-dev
, also updated via a GitHub Action workflow). Thanks to the test coverage of all projects, this can point us to incompatibilities early.
If you have a security issue to report, please contact us at security@prisma.io
CI Status | Branch |
---|---|
latest | |
dev | |
patch-dev |
CI Status |
---|
Download Details:
Author: prisma
Source Code: https://github.com/prisma/prisma-examples
License: Apache-2.0 License