Your prisma and yoga are two seperate entities
**Prisma **is a connection to a database that allows you to access the db with graphl framework, it also allows you access to the graphQL playground
**Yoga **is theJS interface that connects prisma with your frontend and allows queris mutations and logic
In Production
BOTH need their own server
BOTH need schemas
Servers
For prisma and the db we will use Heroku though we could use
-
mongoDB(problems uploading the right schema)
-
MySql(you need a dedicated IP, on GGs that is $40/year)
-
the prisma Cloud - not for prod)
Flow
Initialise Prisma and create a local DB with docker to use offline
Import Yoga and set that up to use the localDB
Set up our frontend and check we can connect
Set up a DB in Heroku
Create a new instance of Prisma init for production and use this new heroku db
Set scripts to use both dev or prod when we see fit
Upload Yoga to now
Now we wil have a Local development setup and a live production setup
Using Prisma βversion 1.34
π πSet up the mysql local db with docker π π
https://www.prisma.io/docs/get-started/01-setting-up-prisma-new-database-JAVASCRIPT-a002/
you may get an error that the port is already taken, at the moment iβm deleting the other containers
$ docker container ls
To view what ports are being used
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63de77bce294 prismagraphql/prisma:1.34 "/bin/sh -c /app/staβ¦" 57 seconds ago Up 56 seconds 0.0.0.0:4467->4467/tcp ac404-backend_prisma_1
88826b630e35 prismagraphql/prisma:1.34 "/bin/sh -c /app/staβ¦" 9 days ago Up About an hour 0.0.0.0:4466->4466/tcp prismayogaherokunow_prisma_1
UPDATE /docker-compose.yml
You can change these ports to find one that is free
ports:
- '4467:4467'
environment:
PRISMA_CONFIG: |
port: 4467
DONβT CHANGE THIS PORT it stays at 3306
default:
connector: mysql
host: mysql
port: 3306
Or you canβ¦. delete all the ports you are using
https://docs.docker.com/engine/reference/commandline/container_ls/
$ docker container ls
$ docker container kill <cont ID>
$ prisma init --endpoint http://localhost:4466
it generates two files prisma.yml and and datamodel.prisma , the minimal needed to run prisma
$ prisma deploy:
You are overriding a db go back and check the ports in /docker-compose.yml
http://localhost:4466. And http://localhost:4466/_admin
Use http://localhost:4466/_admin to add some users and query them π
query users {
users{
name
}
}
Now lets set up the production version, an online DB with Heroku
https://app.prisma.io/your-account-name/servers. β> ADD SERVER
First Create the DB
β> create server β> create new db β> heroku β> update option β> create database
Now you have a DB and you need a server for that
β> set up server β> heroku β> create server
$ prisma deploy -n
And pick the new DB you created
This will auto change your prisma.yml and comment out the local host
#endpoint: http://localhost:4466
endpoint: https://prs-yog-her-now-f085b7bce8.herokuapp.com/PrismaYogaHerokuNow/prod
datamodel: datamodel.prisma
You could switch betwen the two by un-commenting out the one we want to use but instead...
We will need a secret for prod so lets add that to both
create /.env (for dev)
PRISMA_ENDPOINT=http://localhost:4466
PRISMA_SECRET=myPrismaSecret9876543210
create /env.prod (for prod)
PRISMA_ENDPOINT=https://prs-yog-her-now-f085b7bce8.herokuapp.com/PrismaYogaHerokuNow/prod
PRISMA_SECRET=myPrismaSecret9876543210
update /prisma.yml
endpoint: ${env:PRISMA_ENDPOINT}
secret: ${env:PRISMA_SECRET}
datamodel: datamodel.prisma
Now use node to set some scripts
npm init -y
Update /package.json
"scripts": {
"deploy-dev": "prisma deploy --env-file .env",
"deploy-prod": "prisma deploy --env-file .env.prod",
"token-dev": "prisma token --env-file .env",
"token-prod": "prisma token --env-file .env.prod"
},
Now update the data model.prisma to test if when we deploy it updates
type User {
id: ID! @id
name: String!
shoeSize: String!
}
and deploy it using the scripts
$ npm run deploy-dev
your going top get an error
Warnings:
User
! You are creating a required field but there are already nodes present
You can either force it or delete everything in you db. Deleting everythin might be the better option
β οΈ π π₯β οΈ π π₯β οΈ π π₯β οΈ π π₯β οΈ π π₯β οΈ π π₯β οΈ π π₯β οΈ π π₯β οΈ π π₯
You may get an error in the playgournd about a token being out of date
https://www.prisma.io/forum/t/cannot-open-playground-your-token-is-invalid/2194/4
This is the answerπ
https://www.prisma.io/docs/reference/prisma-api/concepts-utee3eiquo#api-token
you create a token in the CLI $ prisma token
π₯EDIT still had problems with the dev and prod versions working
so I cahnaged the secret in env.prod
PRISMA_SECRET=myPrismaSecretForProd
Then useed the new scripts depending on which version i wanted a token for
"token-dev": "prisma token --env-file .env",
"token-prod": "prisma token --env-file .env.prod"
And it seems to work this way
then you manually add it in the http://localhost:4466/_admin. Clik the settings cog
A dev prisma db and server set up locally with docker
A prod prisma db and server set up online with heroku
Prod/Dev env files we can use with a node script to determine wich branch we use
Fixed the TOKEN error in http://db/\_admin
A couple of things to update to get ready for yoga Update / prisma.yml
endpoint: ${env:PRISMA_ENDPOINT}
secret: ${env:PRISMA_SECRET}
datamodel: datamodel.prisma
hooks:
post-deploy:
- graphql get-schema -p prisma
Create /.graphqlconfig.yml
projects:
app:
schemaPath: "src/schema.graphql"
extensions:
endpoints:
default: "http://localhost:4000"
prisma:
schemaPath: "src/generated/prisma.graphql"
extensions:
prisma: prisma.yml
Now deployβ¦ this π is going to generate src/generated/prisma.graphql which we need for yoga
$ npm run deploy-dev
$ npm run deploy-prod
THAT IS ALL FOR PRISMA
some imports
npm i dotenv graphql graphql-cli graphql-yoga nodemon prisma prisma-binding
Connect directly to Prisma DB with prisma-binding
Allows us to use all the tools in the prisma playground in JS
Typedefs = using the generated API typedef, (this is why we use the hook in .graphqlconfig to pull it done into our project)
// This file connects to the remote prisma DB and gives us the ability to query it with JS
const { Prisma } = require('prisma-binding');
// THIS ISN'T IN WESBOS - but you will need it to find the endpoint env
require('dotenv').config();
const db = new Prisma({
//where are your types/schema
typeDefs: 'src/generated/prisma.graphql',
//typeDefs: __dirname + "/schema_prep.graphql",
// where does the db live
endpoint: process.env.PRISMA_ENDPOINT,
secret: process.env.PRISMA_SECRET,
debug: false,
});
module.exports = db;
const { GraphQLServer } = require("graphql-yoga");
// import the resolvers
const Mutation = require("./resolvers/Mutations");
const Query = require("./resolvers/Queries");
// grab the db
const db = require("./db");
// Create the GraphQL Yoga Server
function createServer() {
// console.log('createServer() running πββοΈ');
return new GraphQLServer({
// ANOTHE SCHEMA π± see notes below
typeDefs: 'src/schema.graphql',
// typeDefs: __dirname + "/schema.graphql",
// the above schema will then be matched with an object with the resolvers in
resolvers: {
Mutation,
Query
},
// stops some error
resolverValidationOptions: {
requireResolversForResolveType: false
},
// access the db from the resolvers through 'context'
context: req => ({ ...req, db })
});
}
module.exports = createServer;
a schema of mutations/queries that we want to use
# import * from './generated/prisma.graphql'
type Mutation {
createUser(name: String): User!
}
type Query {
users: [User]!
}
SO FARβ¦.
1. we have created our db
2. We have created the server(Prisma) to connect to the db
3. Created example user schema, a schema of mutations/queries that we want to us
To kick things off
What is deets? https://wesbos.slack.com/threads/convo/C9G96G2UB-1552727085.422700/
//make sure our variables are avaiolable
require('dotenv').config();
//the fn we just created
const createServer = require('./createServer');
//grab the db instance
const db = require('./db');
//run the server fn
const server = createServer();
//using cors here to protect our endpoints
server.start(
{
cors: {
credentials: true,
origin: process.env.FRONTEND_URL
},
},
// a fn that runs when the server spins
deets => {
console.log(`Server is now running on port http://localhost:${deets.port}`);
}
);
const Mutations = {
async createUser(parent, args, ctx, info) {
const user = await ctx.db.mutation.createUser(
{
data: {
...args,
},
},
info
);
console.log("mutation πβ args", args);
return user;
},
};
module.exports = Mutations;
const { forwardTo } = require('prisma-binding');
const Query = {
users: forwardTo('db'),
};
module.exports = Query;
"scripts": {
"start": "nodemon -e js,graphql -x node src/index.js",
"dev": "nodemon -e js,graphql -x node --inspect src/index.js",
"deploy-dev": "prisma deploy --env-file .env",
"deploy-prod": "prisma deploy --env-file .env.prod"
},
$npm run dev
now the yoga wrpapper should be running on localhost:4000
the default port is 4000 if you want to change this add a Port variable to the .env file
PORT=4444
query allUsers {
users{
name
}
}
db.js. with prisma bindings we connect to the db
createServer.js. we create a server use the db connection and our resolvbers to talk to each other
Schema.graphl We create a schema or queries/mutations that our front end can use
index.js - use this to run things in node
In your backend project you have essentially created two apps. one is the prisma server the other is the yoga wrapper
We can use now to deploy our yoga wrapper BUT we have to update the schema so its TS is correct
This is new and from slack Theo Merriamum
https://wesbos.slack.com/threads/convo/C9G96G2UB-1550829164.025300/
"You should not mix graphql imports and js/ts imports. The syntax on the graphql file will be interpreted by graphql-import and will be ignored by ncc (the compiler which reads the __dirname stuff and move the file to the correct directory etc)
In my example 'schema_prep.graphql' is already preprocessed with the imports from the generated graphql file."
**Create β> ** src/writeSchema.js:
write the function writeSchema, it copies the schema generated by prism, and places it in the file schema_prep.graphql
const fs = require('fs');
const { importSchema } = require('graphql-import');
const text = importSchema("src/generated/prisma.graphql");
fs.writeFileSync("src/schema_prep.graphql", text)
Add a script for writeSchema fn and also add it to the deploy scripts
Update β> package.json
add "&& npm run writeSchemaβ to the deploy scripts
add ""writeSchema": "node src/writeSchema.jsββ
"scripts": {
"start": "nodemon -e js,graphql -x node src/index.js",
"dev": "nodemon -e js,graphql -x node --inspect src/index.js",
"deploy-dev": "prisma deploy --env-file .env && npm run write-schema",
"deploy-prod": "prisma deploy --env-file .env.prod && npm run write-schema",
"write-schema": "node src/writeSchema.js",
},
Now run a script to create the new schema
$ npm run write-schema
make sure it ran properly you should have a new file schema_prep.graphql
π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ β οΈππ£π‘οΈ DO THIS OR EVETHING IS F**kedπ‘οΈπ£β οΈπ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯ π₯
**CHANGE **
# import * from './generated/prisma.graphqlβ
TO THIS
# import * from './schema_prep.graphql'
# import * from './schema_prep.graphql'
type Mutation {
createUser(name: String): User!
}
type Query {
users: [User]!
}
With the new schema update the places we use it
const db = new Prisma({
typeDefs: __dirname + "/schema_prep.graphql",
...
});
return new GraphQLServer({
typeDefs: __dirname + '/schema.graphql',
...
});
Okay that the schema taken care off, some other stuff you need
node_modules
.vscode
.env
.env.prod
z_notepad.txt
{
"version": 2,
//update this nameπ and delete this comment
"name": "my-app-name-yoga",
"builds": [
{ "src": "src/index.js", "use": "@now/node-server" }
],
"routes": [
{ "src": "/.*", "dest": "src/index.js" }
],
"env": {
//π change _app_name_ to the name of your app π
"PRISMA_ENDPOINT":"@app_name_prisma_endpoint",
"PRISMA_SECRET":"@app_name_prisma_secret",
// π You dont know this yet as we havent set up the frontend so add it anyway add app_name_frontend_url TBD
"FRONTEND_URL":"@app_name_frontend_url",
}
}
GIVE THEM A UNIQUR HANDLE as they gloabbly sit in your now account. so βfonrtend_urlβ is noooo good
$ now secret add myAppName_frontend_url https://myCoolDomainName
$ now