Logo

dev-resources.site

for different kinds of informations.

A Simple Crud App With Prisma, Express, and PostgreSQL

Published at
2/21/2024
Categories
webdev
prisma
postgres
beginners
Author
FredAbod
Categories
4 categories in total
webdev
open
prisma
open
postgres
open
beginners
open
A Simple Crud App With Prisma, Express, and PostgreSQL

Building a Simple Blog App with Express, Prisma, and PostgreSQL

In this tutorial, I will take you step by step to building a simple(CRUD) blog application. The app will support creating, retrieving, updating, and deleting blog posts.

Prerequisites

Make sure you have Node.js and npm installed on your machine, and you have PostgreSQL set up with a database.

I hope you know how to setup a Postgres database๐Ÿ˜‰๐Ÿ˜‰๐Ÿ˜‰. If you don't You have to๐Ÿ˜Ž,

Let's Dive Right in

Diving

Step 1: Project Setup

Create a new directory for your project and initialize it with npm:

mkdir prisma-express-blog-app
cd prisma-express-blog-app
npm init -y

Step 2: We'll Install Our Project Dependencies

npm install express @prisma/client dotenv

Step 3: We'll Set Up Prisma

npx prisma init

This would install the necessary files and folders for prisma

Step 4: We'll configure our prisma schema to look like this

// prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// Post model represents individual blog posts
model Post {
  id        Int       @id @default(autoincrement())
  title     String
  content   String
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
}

Step 5: We'll Configure our .env file to contain our postgres database URL. Mine looks like this

DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"

I'll edit that and add my postgresDb URL

DATABASE_URL="postgresql://postgres:qwer@localhost:5432/mydb?schema=public"

You'll change your password and database name

Step 6: We'll Create A Database Migration

npx prisma migrate dev

This would create a migration for you and add the folder, when you open the folder you see your migration.sql file which looks exactly like your schema

-- CreateTable
CREATE TABLE "Post" (
    "id" SERIAL NOT NULL,
    "title" TEXT NOT NULL,
    "content" TEXT NOT NULL,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,

    CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
);

Step 7: Now we'll create our main entry file and call it app.js.

We'll initialize express, dotenv our middleware and also listen to our port

const express = require("express");
require("dotenv").config();

const app = express();
app.use(express.json());
const port = process.env.PORT || 3000;

app.get("/", (req, res) => {
res.send("Welcome Tou Prisma, Express And PSQL Tutorial");
});

app.listen(port, () => {
console.log(Server listening on ${port});
});

## Step 8: Now lets import prismaClient and configure it, add this lines of code to your `app.js` file
```javascript
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient();

Step 9: Now we add our first route, which would be to add a blog

This route would look like this:

app.post("/post", async (req, res) => {
  try {
    const { title, content } = req.body;
    if (!title || !content) {
      return res
        .status(400)
        .json({ message: "Please input Title Anc Content" });
    }
const blog = await prisma.post.create({
  data: { title, content },
});

return res
  .status(201)
  .json({ message: "Blog created successfully", data: blog });

} catch (error) {
return res.status(500).json({ message: "Error creating blog" });
}
});

After adding this to your `app.js` file we should test that route before moving on, my route looks like this `http://localhost:4500/post` 
> I got my response after testing

![Create Post](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vju5s5b93fi961a5ypzb.png)
> Add as much Blogs as Possible

## Step 10: Stretch Your Fingers ๐Ÿ˜๐Ÿ˜

![Stretch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftkqox4dpbtnaihd0o4g.gif)

## Step 11: Now we'll add a Route to get all Blogs and tell us the number of blogs available
```javascript
app.get("/posts", async (req, res) => {
  try {
    const blogs = await prisma.post.findMany();
    return res.status(201).json({ data: blogs.length, blogs });
  } catch (error) {
    return res.status(500).json({ message: "Error fetching blogs" });
  }
});

after testing:

Get All

Step 12: We'll add a route to get a single blog by title

app.get("/get", async (req, res) => {
    const { title } = req.query;
    try {
      const blog = await prisma.post.findFirst({
        where: { title }
      });
      if (blog) {
        return res.status(200).json(blog);
      } else {
        return res.status(404).json({ message: "Blog not found" });
      }
    } catch (error) {
      console.log(error);
      return res.status(500).json({ message: "Error fetching blog" });
    }
  });

Step 13: I'll add some more routes, you can add and test for yourself

Now I finally have this:

const express = require("express");
const { PrismaClient } = require("@prisma/client");
require("dotenv").config();

const prisma = new PrismaClient();

const app = express();
app.use(express.json());
const port = process.env.PORT || 3000;

app.get("/", (req, res) => {
res.send("Welcome to Prisma, Express, and PSQL Tutorial");
});

// Create a blog
app.post("/post", async (req, res) => {
try {
const { title, content } = req.body;
if (!title || !content) {
return res
.status(400)
.json({ message: "Please input Title and Content" });
}

const blog = await prisma.post.create({
  data: { title, content },
});

return res
  .status(201)
  .json({ message: "Blog created successfully", data: blog });

} catch (error) {
return res.status(500).json({ message: "Error creating blog" });
}
});

// Get all blogs
app.get("/posts", async (req, res) => {
try {
const blogs = await prisma.post.findMany();
return res.status(201).json({ data: blogs.length, blogs });
} catch (error) {
return res.status(500).json({ message: "Error fetching blogs" });
}
});

// Get a single blog by title
app.get("/get", async (req, res) => {
const { title } = req.query;
try {
const blog = await prisma.post.findFirst({
where: { title }
});
if (blog) {
return res.status(200).json(blog);
} else {
return res.status(404).json({ message: "Blog not found" });
}
} catch (error) {
console.log(error);
return res.status(500).json({ message: "Error fetching blog" });
}
});

// Update a blog by id
app.put("/post/:id", async (req, res) => {
const { id } = req.params;
const { title, content } = req.body;
try {
const updatedBlog = await prisma.post.update({
where: { id: parseInt(id) },
data: { title, content },
});
return res.json({
message: "Blog updated successfully",
data: updatedBlog,
});
} catch (error) {
console.log(error);
return res.status(500).json({ message: "Error updating blog" });
}
});

// Delete a blog by id
app.delete("/post/:id", async (req, res) => {
const { id } = req.params;
try {
await prisma.post.delete({
where: { id: parseInt(id) },
});
return res.json({ message: "Blog deleted successfully" });
} catch (error) {
return res.status(500).json({ message: "Error deleting blog" });
}
});

app.listen(port, () => {
console.log(Server listening on ${port});
});

> And that is a comprehensive CRUD app using Prisma, PSQL, and express
[Link to Github Repo Containing The Code](https://github.com/FredAbod/Prisma-Tutorial)
## Thank you for taking the time to read ๐Ÿฅฐ๐Ÿฅฐ, I hope this was helpful, Don't Forget to drop a like and follow๐Ÿ˜‹๐Ÿ˜‹. See You on the Next One๐Ÿค—

![Bow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2go8l3113h2kw6enp2d5.gif)

Featured ones: