Pagina principale

Daniele Irsuti
frontend developer

Prisma, non un ORM tradizionale

Cos'è prisma? Perché usarlo? Una panoramica introduttiva per cercare di capirlo

Difficile dire cos’è Prisma, forse riesce meglio dire cosa non è. Non è un ORM tradizionale, non crea dei modelli (o entità) nel linguaggio in cui stiamo sviluppando, ma crea degli schema in una strana estensione .prisma.

Il flusso

Sulla documentazione ufficale di Prisma c’è la stessa immagine che riporto sotto per dare un’idea ad altissimo livello su come lavora Prisma dietro le quinte.

Prisma si interfaccia con il database come segue:

  • Connettendosi al DB, innanzitutto;

  • Introspeziona lo schema del DB e genera il datamodel (che sarà proprio datamodel.prisma, il file prodotto di cui ne ho già accennato)

  • Genera il client, un codice autogenerato che può essere integrato nel nostro software nel linguaggio che scegliamo, lo spiego meglio più avanti.

Creare un’applicazione Prisma

Nota: Per la mia applicazione d’esempio, ho utilizzato un database mongo che avevo su una virtual machine. Faccio questa doverosa precisazione perché l’introspezione su mongodb alla data in cui scrivo non è supportata e questo presenta un ostacolo se l’architettura di partenza è pensata database-first, perché sarete costretti a creare tutti gli schema manualmente. Sorry.

Per utilizzare Prisma a pieno occurrono alcuni passaggi preliminari:

  • Bisogna avere installato sulla propria macchina Docker (e ahimè non si scappa);

  • Installare la CLI di Prisma:

    npm install -g prisma

o per mac:

brew tap prisma/prisma
brew install prisma

Adesso ti servirà il microservizio di Prisma, contenuto in un container docker per agganciarci al nostro database e generare lo schema. Per farlo, ci metteremo sulla directory scelta del progetto e creeremo il file docker-compose.yml, che ho già opportunamente modificato per farlo funzionare con il mio db:

version: '3'
services:
prisma:
image: prismagraphql/prisma:1.28
restart: always
ports:
- "4468:4468"
environment:
PRISMA_CONFIG: |
port: 4468
databases:
default:
connector: mongo
uri: mongodb://172.22.156.180
database: "test"
mongo:
image: mongo:3.6
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: prisma
MONGO_INITDB_ROOT_PASSWORD: prisma
ports:
- "27017:27017"
volumes:
- mongo:/var/lib/mongo
volumes:
mongo:

La mia prima impressione è stata:

Pura. Magia. Nera.

Tentando di semplificare mi sono concentrato su:

  • Connection string del database

  • Porta che utilizzerà il servizio

Una volta impostate entrambe, Prisma introspezionerà il db e genererà lo schema, ma solo eseguendo il seguente comando:

docker-compose up -d

Se l’esito del comando dato sarà positivo, vedrai che si è generato un file denominato datamodel.prisma che conterrà quanto segue come default:

type User {
id: ID! @unique
name: String!
}

Bene, hai il tuo schema generato ma nonostante ciò non puoi ancora interagire con il db. Per farlo ci serve che prisma generi per noi un servizio che ci permetta di interrogare il db e fare delle operazioni. Per questo, creeremo un secondo file ma stavolta generandolo tramite questo comando:

prisma init --endpoint http://localhost:4468

Questo genererà un file prisma.yml che in questa introduzione userai per generare il client e inizializzare il servizio.

Il file prisma.yml si presenterà così al suo interno:

endpoint: http://localhost:4468
datamodel: datamodel.prisma

A questo aggiungi le due proprietà con i relativi sotto elementi, il perché lo spiego a seguire:

endpoint: http://localhost:4468
datamodel: datamodel.prisma
databaseType: document
generate:
- generator: javascript-client
output: ./generated/prisma-client/

NOTE: Da documentazione ufficiale, se il db è Mongo deve essere esplicitata la proprietà databaseType a document. Prisma su questo fronte mi da’ l’impressione di essere ancora un po’ acerbo per mongo ma sono sicuro che subirà ancora aggiornamenti non lontani dalla data in cui scrivo questo post.

La proprietà generate esplicita in quale linguaggio il codice per generare il client, deve essere prodotto. Dal momento che mi trovo su node ho ovviamente optato per il javascript-generator e impostato come output ./generated/prisma-client/, ma tu vai e sii l’artefice del tuo destino.

Fatto ciò, esegui il comando che genererà, come da te indicato, il codice:

prisma generate

Se adesso tu andassi a dare un’occhiata al file nel percorso ./generated/prisma-client/schema-prisma.js troveresti qualcosa di familiare… il datamodel.prisma riscritto come proprietà typeDefs!

module.exports = {
typeDefs: // Code generated by Prisma (prisma@1.28.5). DO NOT EDIT.
// Please don't change this file manually but run `prisma generate` to update it.
// For more information, please read the docs: https://www.prisma.io/docs/prisma-client/
//... omesso il resto per brevità
}

Tornando alla directory principale, installa le dipendenze per far funzionare il codice staticamente prodotto:

npm init -y
npm install --save prisma-client-lib

Crea il file index.js e scrivi una funzione che crei un utente:

const { prisma } = require('./generated/prisma-client')
// A `main` function so that we can use async/await
async function main() {
// Create a new user called `Alice`
const newUser = await prisma.createUser({ name: 'Alice' })
console.log(`Created new user: ${newUser.name} (ID: ${newUser.id})`)
// Read all users from the database and print them to the console
const allUsers = await prisma.users()
console.log(allUsers)
}
main().catch(e => console.error(e))

Finito! Adesso mettiamo su il servizio…

Fatto questo, possiamo dare il finale ed agognato comando:

prisma deploy

Quest’ultimo avvierà un servizio che ti permetterà di interagire con il db con lo schema graphQL. In console vedrai un messaggio come questo:

Deploying service `default` to stage `default` to server `local` 566ms

L’endpoint che puoi consultare sarà lo stesso che avete dichiarato all’inizio, ossia http://localhost:4468

Se a questo punto tu dessi il comando:

node index

Verrà:

  • generato un utente di nome “Alice”

  • ritornata una lista di tutti gli utenti

Esplorando il servizio con il playground offerto da yoga (l’editor visuale online per eseguire le query in graphql) hai a disposizione tutta la documentazione necessaria per fare mutation, query e subscription.

Se utilizzi quel codice staticamente prodotto e decidi di aggiornare il datamodel.prisma ricordati che devi far rigenererare al tuo client, per farlo ridai sempre il comando:

prisma generate

Link utili

Prisma docs (Sito ufficiale)

Daniele Irsuti

Note sull'autore

Daniele irsuti è specializzato in applicazioni React, React Native e vanilla. È un appassionato di grafica, psicologia e scrittura