Creating a REST API with HonoJS and Prisma ORM

Introduction

This guide will walk you through the steps to create a REST API using HonoJS and Prisma ORM. HonoJS is a lightweight web framework for Node.js, and Prisma is a modern ORM that simplifies database access.

Prerequisites

  • Node.js installed
  • PostgreSQL or any other supported database installed and running
  • Basic knowledge of JavaScript and Node.js

Setup

  1. Initialize a new Node.js project

     mkdir hono-prisma-api
     cd hono-prisma-api
     npm init -y
  2. Install required dependencies

     npm install hono prisma @prisma/client
  3. Initialize Prisma

     npx prisma init
    This will create a `prisma` folder with a `schema.prisma` file and a `.env` file.

Configure Prisma

  1. Update the .env file

    Set the DATABASE_URL to your database connection string.

     DATABASE_URL="postgresql://user:password@localhost:5432/mydatabase"
  2. Define your data model

    Edit prisma/schema.prisma to define your data model. For example:

     datasource db {
       provider = "postgresql"
       url      = env("DATABASE_URL")
     }
    
     generator client {
       provider = "prisma-client-js"
     }
    
     model User {
       id    Int     @id @default(autoincrement())
       name  String
       email String  @unique
     }
  3. Run Prisma migrations

     npx prisma migrate dev --name init
     npx prisma generate

Create the API with HonoJS

  1. Create a basic HonoJS server

    Create a server.js file:

     const { Hono } = require('hono');
     const { PrismaClient } = require('@prisma/client');
    
     const app = new Hono();
     const prisma = new PrismaClient();
    
     app.get('/', (c) => c.json({ message: 'Hello, HonoJS!' }));
    
     app.listen(3000, () => {
       console.log('Server running on http://localhost:3000');
     });
  2. Add CRUD operations

    Update server.js to include CRUD operations:

     const { Hono } = require('hono');
     const { PrismaClient } = require('@prisma/client');
    
     const app = new Hono();
     const prisma = new PrismaClient();
    
     app.get('/', (c) => c.json({ message: 'Hello, HonoJS!' }));
    
     app.get('/users', async (c) => {
       const users = await prisma.user.findMany();
       return c.json(users);
     });
    
     app.get('/users/:id', async (c) => {
       const { id } = c.req.param();
       const user = await prisma.user.findUnique({
         where: { id: parseInt(id) }
       });
       return user ? c.json(user) : c.json({ error: 'User not found' }, 404);
     });
    
     app.post('/users', async (c) => {
       const data = await c.req.json();
       const newUser = await prisma.user.create({ data });
       return c.json(newUser, 201);
     });
    
     app.put('/users/:id', async (c) => {
       const { id } = c.req.param();
       const data = await c.req.json();
       const updatedUser = await prisma.user.update({
         where: { id: parseInt(id) },
         data
       });
       return c.json(updatedUser);
     });
    
     app.delete('/users/:id', async (c) => {
       const { id } = c.req.param();
       await prisma.user.delete({
         where: { id: parseInt(id) }
       });
       return c.json({ message: 'User deleted' });
     });
    
     app.listen(3000, () => {
       console.log('Server running on http://localhost:3000');
     });

Testing the API

You can use tools like Postman or curl to test your API endpoints. Here are some example commands using curl:

  • Get all users

      curl http://localhost:3000/users
  • Get a user by ID

      curl http://localhost:3000/users/1
  • Create a new user

      curl -X POST http://localhost:3000/users -H "Content-Type: application/json" -d '{"name": "John Doe", "email": "john@example.com"}'
  • Update a user

      curl -X PUT http://localhost:3000/users/1 -H "Content-Type: application/json" -d '{"name": "John Smith"}'
  • Delete a user

      curl -X DELETE http://localhost:3000/users/1

Conclusion

You now have a basic REST API using HonoJS and Prisma ORM. You can expand this example by adding more models and routes to fit your application's requirements.