# Prisma with JavaScript Integration Setup Guide
This guide provides step-by-step instructions for integrating Prisma ORM with a JavaScript application.
## Prerequisites
- Node.js and npm installed
- JavaScript project initialized
- PostgreSQL database (or any other supported database)
## Installation
1. Install Prisma and its dependencies:
```bash
npm install @prisma/client
npm install -D prisma
```
2. Initialize Prisma in your project:
```bash
npx prisma init
```
## Database Schema
1. Define your schema in `prisma/schema.prisma`:
```prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
## Database Client Setup
1. Create a database client file `src/db.js`:
```javascript
const { PrismaClient } = require('@prisma/client')
let prisma
// This is needed because in development we don't want to restart
// the server with every change, but we want to make sure we don't
// create a new connection to the DB with every change either.
if (process.env.NODE_ENV === 'production') {
prisma = new PrismaClient()
} else {
if (!global.prisma) {
global.prisma = new PrismaClient()
}
prisma = global.prisma
}
module.exports = prisma
```
## Models Implementation
1. Create a users model `src/models/user.js`:
```javascript
const prisma = require('../db')
const userModel = {
async getUsers() {
try {
return await prisma.user.findMany({
include: {
posts: true
}
})
} catch (error) {
console.error('Failed to fetch users:', error)
throw error
}
},
async getUserById(id) {
try {
return await prisma.user.findUnique({
where: { id },
include: {
posts: true
}
})
} catch (error) {
console.error(`Failed to fetch user ${id}:`, error)
throw error
}
},
async createUser(data) {
try {
return await prisma.user.create({
data,
include: {
posts: true
}
})
} catch (error) {
console.error('Failed to create user:', error)
throw error
}
},
async updateUser(id, data) {
try {
return await prisma.user.update({
where: { id },
data,
include: {
posts: true
}
})
} catch (error) {
console.error(`Failed to update user ${id}:`, error)
throw error
}
},
async deleteUser(id) {
try {
return await prisma.user.delete({
where: { id }
})
} catch (error) {
console.error(`Failed to delete user ${id}:`, error)
throw error
}
}
}
module.exports = userModel
```
2. Create a posts model `src/models/post.js`:
```javascript
const prisma = require('../db')
const postModel = {
async getPosts() {
try {
return await prisma.post.findMany({
include: {
author: true
}
})
} catch (error) {
console.error('Failed to fetch posts:', error)
throw error
}
},
async getPostById(id) {
try {
return await prisma.post.findUnique({
where: { id },
include: {
author: true
}
})
} catch (error) {
console.error(`Failed to fetch post ${id}:`, error)
throw error
}
},
async createPost(data) {
try {
return await prisma.post.create({
data,
include: {
author: true
}
})
} catch (error) {
console.error('Failed to create post:', error)
throw error
}
},
async updatePost(id, data) {
try {
return await prisma.post.update({
where: { id },
data,
include: {
author: true
}
})
} catch (error) {
console.error(`Failed to update post ${id}:`, error)
throw error
}
},
async deletePost(id) {
try {
return await prisma.post.delete({
where: { id }
})
} catch (error) {
console.error(`Failed to delete post ${id}:`, error)
throw error
}
}
}
module.exports = postModel
```
## Express.js API Implementation
1. Install Express.js:
```bash
npm install express cors
```
2. Create an Express server `src/server.js`:
```javascript
const express = require('express')
const cors = require('cors')
const userModel = require('./models/user')
const postModel = require('./models/post')
const app = express()
app.use(cors())
app.use(express.json())
// User routes
app.get('/api/users', async (req, res) => {
try {
const users = await userModel.getUsers()
res.json(users)
} catch (error) {
res.status(500).json({ error: 'Failed to fetch users' })
}
})
app.get('/api/users/:id', async (req, res) => {
try {
const user = await userModel.getUserById(parseInt(req.params.id))
if (!user) {
return res.status(404).json({ error: 'User not found' })
}
res.json(user)
} catch (error) {
res.status(500).json({ error: `Failed to fetch user ${req.params.id}` })
}
})
app.post('/api/users', async (req, res) => {
try {
const user = await userModel.createUser(req.body)
res.status(201).json(user)
} catch (error) {
res.status(500).json({ error: 'Failed to create user' })
}
})
app.put('/api/users/:id', async (req, res) => {
try {
const user = await userModel.updateUser(parseInt(req.params.id), req.body)
res.json(user)
} catch (error) {
res.status(500).json({ error: `Failed to update user ${req.params.id}` })
}
})
app.delete('/api/users/:id', async (req, res) => {
try {
await userModel.deleteUser(parseInt(req.params.id))
res.status(204).end()
} catch (error) {
res.status(500).json({ error: `Failed to delete user ${req.params.id}` })
}
})
// Post routes
app.get('/api/posts', async (req, res) => {
try {
const posts = await postModel.getPosts()
res.json(posts)
} catch (error) {
res.status(500).json({ error: 'Failed to fetch posts' })
}
})
app.get('/api/posts/:id', async (req, res) => {
try {
const post = await postModel.getPostById(parseInt(req.params.id))
if (!post) {
return res.status(404).json({ error: 'Post not found' })
}
res.json(post)
} catch (error) {
res.status(500).json({ error: `Failed to fetch post ${req.params.id}` })
}
})
app.post('/api/posts', async (req, res) => {
try {
const post = await postModel.createPost(req.body)
res.status(201).json(post)
} catch (error) {
res.status(500).json({ error: 'Failed to create post' })
}
})
app.put('/api/posts/:id', async (req, res) => {
try {
const post = await postModel.updatePost(parseInt(req.params.id), req.body)
res.json(post)
} catch (error) {
res.status(500).json({ error: `Failed to update post ${req.params.id}` })
}
})
app.delete('/api/posts/:id', async (req, res) => {
try {
await postModel.deletePost(parseInt(req.params.id))
res.status(204).end()
} catch (error) {
res.status(500).json({ error: `Failed to delete post ${req.params.id}` })
}
})
const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
```
## Frontend Implementation
1. Create a simple HTML frontend `public/index.html`:
```html
Blog App
Users
Add User
Posts
Add Post
```
## Environment Setup
1. Create `.env` file:
```env
DATABASE_URL="postgresql://user:password@localhost:5432/dbname?schema=public"
PORT=3000
```
2. Add `.env` to `.gitignore`:
```
.env
node_modules
```
## Database Migration
1. Generate Prisma Client:
```bash
npx prisma generate
```
2. Create and apply migrations:
```bash
npx prisma migrate dev --name init
```
## Best Practices
1. Database Connection
- Use connection pooling in production
- Keep environment variables secure
- Use migrations for schema changes
2. Error Handling
- Implement proper error handling in models
- Show user-friendly error messages
- Log errors for debugging
3. Performance
- Use proper indexes in schema
- Implement pagination for large datasets
- Cache frequently accessed data
4. API Design
- Follow RESTful conventions
- Implement proper validation
- Use appropriate HTTP status codes
5. Security
- Validate input data
- Implement proper authentication
- Use prepared statements (handled by Prisma)
- Implement CORS properly
## Development Workflow
1. Make schema changes in `schema.prisma`
2. Generate migration:
```bash
npx prisma migrate dev --name
```
3. Update Prisma Client:
```bash
npx prisma generate
```
4. Use Prisma Studio for database management:
```bash
npx prisma studio
```
5. Start the development server:
```bash
node src/server.js
```