A simple backend API for a todo application that uses Prisma ORM with a database to perform CRUD (Create, Read, Update, Delete) operations on todo items. Built with Node.js and Express.js.
- Features
- Technologies
- Prerequisites
- Installation
- Configuration
- Running the Application
- API Endpoints
- Database
- Prisma
- Testing
- Contributing
- License
- Create new todo items
- Read all todo items
- Update existing todo items
- Delete todo items
- Prisma ORM for database operations
- Type-safe database queries
- Database migrations
- RESTful API design
- Node.js - JavaScript runtime
- Express.js - Web framework for Node.js
- Prisma ORM - Next-generation Node.js and TypeScript ORM
- PostgreSQL - Relational database (configurable)
- REST API - Standard HTTP methods
Before running this project, ensure you have the following installed:
- Node.js (version 18 or higher)
- npm (usually comes with Node.js)
- Prisma CLI
- PostgreSQL (or your preferred database)
-
Clone the repository
git clone https://github.com/Anastand/backend-todo.git cd backend-todo -
Install dependencies
npm install
-
Install Prisma Client
npx prisma generate
Create a .env file in the root directory and add your configuration:
# Database configuration
DATABASE_URL="postgresql://username:password@localhost:5432/todo_app?schema=public"
# Server configuration
PORT=3000
NODE_ENV=development
# Optional: JWT secret for authentication (if implemented)
JWT_SECRET=your_jwt_secret_here-
Install and start PostgreSQL on your local machine or use a cloud database service.
-
Create a database named
todo_app(or update theDATABASE_URLto match your database name). -
Update DATABASE_URL in your
.envfile with your PostgreSQL connection details.
Before running the application, set up your database:
# Generate Prisma Client
npx prisma generate
# Run database migrations
npx prisma migrate dev --name init
# Seed the database (optional)
npx prisma db seednpm run devThis starts the server with nodemon for automatic restarts on file changes.
npm startThe server will be available at http://localhost:3000.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/todos |
Get all todo items |
GET |
/api/todos/:id |
Get a specific todo by ID |
POST |
/api/todos |
Create a new todo item |
PUT |
/api/todos/:id |
Update a todo item |
DELETE |
/api/todos/:id |
Delete a todo item |
Request Body:
{
"title": "Learn Prisma",
"description": "Complete the backend todo app with Prisma ORM",
"completed": false
}Response (201):
{
"id": 1,
"title": "Learn Prisma",
"description": "Complete the backend todo app with Prisma ORM",
"completed": false,
"createdAt": "2025-09-22T10:00:00.000Z",
"updatedAt": "2025-09-22T10:00:00.000Z"
}Response (200):
[
{
"id": 1,
"title": "Learn Prisma",
"description": "Complete the backend todo app with Prisma ORM",
"completed": false,
"createdAt": "2025-09-22T10:00:00.000Z",
"updatedAt": "2025-09-22T10:00:00.000Z"
}
]{
"error": "Todo not found",
"status": 404
}This application uses PostgreSQL with Prisma ORM for data persistence.
The database schema is defined in prisma/schema.prisma:
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Todo {
id Int @id @default(autoincrement())
title String
description String?
completed Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("todos")
}# Generate Prisma Client
npx prisma generate
# Run migrations
npx prisma migrate dev
# Reset database (development only)
npx prisma migrate reset
# Seed database
npx prisma db seed
# Studio (Database GUI)
npx prisma studioThe Prisma Client is generated and used throughout the application for type-safe database operations.
Example usage in a controller:
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
async function getAllTodos(req, res) {
try {
const todos = await prisma.todo.findMany({
orderBy: { createdAt: 'desc' }
});
res.json(todos);
} catch (error) {
res.status(500).json({ error: error.message });
}
}To seed the database with sample data, create a seed script in prisma/seed.js:
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
async function main() {
const todos = [
{ title: 'Sample Todo 1', description: 'This is a sample todo' },
{ title: 'Sample Todo 2', completed: true },
];
for (const todo of todos) {
await prisma.todo.create({
data: todo,
});
}
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});Add to package.json:
{
"prisma": {
"seed": "node prisma/seed.js"
}
}To run tests:
npm testAvailable test scripts:
npm test- Run all testsnpm run test:unit- Run unit testsnpm run test:integration- Run integration tests
Note: Tests use an in-memory SQLite database for faster execution.
backend-todo/
├── prisma/
│ ├── schema.prisma # Database schema
│ └── seed.js # Database seeding
├── src/
│ ├── controllers/ # Request handlers
│ ├── routes/ # API routes
│ ├── middleware/ # Custom middleware
│ ├── config/ # Configuration files
│ └── utils/ # Utility functions
├── tests/ # Test files
├── .env.example # Environment variables template
├── .gitignore
└── package.json
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Please ensure your code follows these guidelines:
- Write clear commit messages
- Add tests for new features
- Update Prisma schema and run migrations for database changes
- Keep the code DRY and well-documented
- Follow existing code style
This project is licensed under the MIT License - see the LICENSE file for details.
For questions or suggestions, please open an issue on GitHub or contact me at:
- GitHub: @Anastand
Built with ❤️ using Prisma for modern database workflows