DEV Community

Elif Nur Turk
Elif Nur Turk

Posted on

Exploring Server-Side Rendering and Database Operations in Nuxt.js with Prisma ORM

Exploring Server-Side Rendering and Database Operations in Nuxt.js with Prisma ORM

Nuxt.js, a powerful Vue.js framework and with the release of Nuxt 3, the framework has doubled down on its commitment to server-side rendering (SSR).

In this article, we’ll delve into the world of server-side coding with Nuxt 3. We’ll explore what server-side rendering means in the context of Nuxt 3, how to leverage it effectively in your projects. If you are looking for an upgrade in Nuxt 3, this guide will equip you with the knowledge and tools you need to harness the full potential of server-side coding in your Vue applications.

Assuming you already have a database connection established through Prisma ORM, we’ll dive into leveraging the power of Nuxt 3’s server-side rendering capabilities alongside Prisma’s robust data modeling features. Underlined sentences will take you to the relevant article. If you haven’t set up Prisma ORM yet, don’t worry; integrate Prisma ORM into your existing project simply follow the instructions in the Prisma documentation to get started with setting up your database connection and generating your Prisma client.

No matter which database you use, the process will remain the same unless you have the DATABASE_URL in your .env file. Once you have your Prisma folder and schema.prisma file configured, we’ll proceed with defining our models to facilitate smooth data management within our Nuxt 3 application. We will read the outputs via Postman.

The folder architecture will primarily resemble;

    | assets/
    | components/
    | pages/
    | prisma/
    | |- schema.prisma/
    | public/
    | server/
    | |- api/
    |- app.vue
    |- nuxt.config.ts
    |- package.json
    |- yarn.lock
    |- README.md
    |- tsconfig.json

Enter fullscreen mode Exit fullscreen mode

This is the Prisma model creation process. We’ll employ this model to define all CRUD operations.

/prisma/schema.prisma

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

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

model Users {
  Id       Int      @id @default(autoincrement()) // Primary key
  Name     String
  Surname  String
  Email    String   @unique
  CreateAt DateTime @default(now())          
}`
Enter fullscreen mode Exit fullscreen mode

Now you can migrate your model into your database on terminal.

We’re transitioning to Nuxt 3 server-side rendering. Let’s begin by setting up the following folder structure. We’ll implement functionalities to create, update, and delete users, as well as display them individually by their IDs. We’ll utilize HTTP methods to perform these CRUD operations directly through API endpoint URLs.

| server/
| |- api/
| | |- users/
| | | |- [id].get.js
| | | |- [id].delete.js
| | | |- [id].put.js
| | |- users.get.js
| | |- users.post.js
| |- utils/
| | |- prisma.js
|- app.vue
|- nuxt.config.ts
|- package.json
|- yarn.lock
|- README.md
|- tsconfig.json

To prevent repetition of the Prisma import in every server file, we’ve created a prisma.js file in the util directory. Within it, we place the following code. This way, there's no need to repeatedly import Prisma in each server file.

/server/utils/prisma.js

   import { PrismaClient } from '@prisma/client';

    const prisma = new PrismaClient();

    export default prisma;

Enter fullscreen mode Exit fullscreen mode

We’ve streamlined the process by directly importing utils in Nuxt. You won’t find the need to configure routes in any config file.

We’ll provide detailed documentation for each file, including its code and the corresponding output we’ve verified using Postman. Lets start!

/server/api/users.get.js

  // Event handler for DELETE request to delete a user
    export default defineEventHandler(async () => {
        try {
        const users = await prisma.users.findMany();
        return users;   
        } catch (error) {
          // Return error if fetching users fails
          return {
            status: 500,
            body: { message: 'Failed to fetch users' }
          };
        }
    });
Enter fullscreen mode Exit fullscreen mode

There is all users over there

/server/api/users.post.js

    export default defineEventHandler(async (event) => {
      const { Name, Surname, Email } = await readBody(event)

      const user = await prisma.users.create({
        data: {
          Name, Surname, Email
        },
      })
      return user
    })
Enter fullscreen mode Exit fullscreen mode

In Postman, ensure to include the necessary body information for posting data, then select the POST method from the dropdown menu located at the top left corner. After the Post method, it will return the new created user.

Now, we can initiate the usage of CRUD operations targeting specific user IDs. Make the postman method get again and see the user with id “1”

/server/api/users/[id].get.js


    export default defineEventHandler(async (event) => {
      const user = await prisma.users.findUnique(({
        where: {
          Id: parseInt(event.context.params.id)
        },
        //include: { author: true }
      }))
      return user;
    });
Enter fullscreen mode Exit fullscreen mode

Lets delete the test user back now. We choose the method “DELETE” and add user id the URL

/server/api/users/[id].delete.js

    export default defineEventHandler(async (event) => {
        const user = await prisma.users.delete(({
          where: {
            Id: parseInt(event.context.params.id)
          },
          //include: { author: true }
        }))
        return user;
      });
Enter fullscreen mode Exit fullscreen mode

Let’s see how the change the user data via “PUT” method.

/server/api/users/[id].put.js



    export default defineEventHandler(async (event) => {
        const body = await readBody(event)
        const name = body.Name
        const surname = body.Surname
        const email = body.Email

        const updateUser = await prisma.users.update({
          where: {
            Id: parseInt(event.context.params.id)},
            data: {
                Name: name,
                Surname: surname,
                Email: email,
              },
        });
        return updateUser;
    });

Enter fullscreen mode Exit fullscreen mode

We’re injecting the “fresh data” into the body tag, just like we do when drafting models. Before and after send operation.

You can either update all variables with new data or choose to update only the name. Any changes made in the body tag content will affect the existing data.

In this article, I outlined the foundational structure and shared some essential insights into crafting a server using Nuxt. My aim is to provide valuable assistance to developers keen on advancing in this field.

And if you’re ready to dive into the code, I’ve got the full repo waiting for you right **here**. Explore and experiment!”

“In the grand canvas of the big picture, embark on a journey of painting each detail.”

See you in next article, happy coding!

References

Top comments (0)