rockets4all
rockets4all

Reputation: 876

How to add a string before a query return in prisma?

I have a backend that uses NestJS and Prisma for the DB. I have an attachments model that holds the location of files. Currently I save the files with the entire route needed for pulling it back out like so 'http://127.0.0.1:5000/api/123.jpg'. I want to save it as '/123.jpg' and have prisma add the domain string in front http://127.0.0.1:5000/api so the server can be easily moved to different domains.

I have a for loop that goes through the queries and adds the domain as I want, but I have to do this for every association and route in my site. Do you all know a good way for prisma to handle this as the query is performed?

schema.prisma

model Attachment {
  id                        Int                   @id @default(autoincrement())
  //is there a way to inject a domain url string in front of the string this sends out?
  thumbnail                 String?
  original                  String?
}

Solved

I put @ConnorFogarty's answer into /prisma/prisma.ts as shown below:

import { PrismaClient } from '@prisma/client';
import { APP_URL } from '../src/common/constants';

let prisma: PrismaClient;

if (process.env.NODE_ENV === 'production') {
  prisma = new PrismaClient();
} else {
  if (!global.prisma) {
    global.prisma = new PrismaClient();
  }
  prisma = global.prisma;
}

//middleware to add server link to all requests for Attachments with original/thumbnail
prisma.$use(async (params, next) => {
  console.log('params', params)
  if (params.model == 'Attachment' && params.action == 'findMany') {
    params.args.data.thumbnail = APP_URL + params.args.data.thumbnail;
  }

  return next(params)
})

export default prisma;

In my console you can see params is missing params.args.data

params {
  args: { include: { avatar: true, addresses: true } },
  dataPath: [],
  runInTransaction: false,
  action: 'findMany',
  model: 'User'
}

Upvotes: 1

Views: 1037

Answers (1)

Connor Fogarty
Connor Fogarty

Reputation: 326

Prisma middleware allows you to run code before or after a query. In your case, you can define a middleware method for findMany (or whatever other queries you run) that inserts the server url before the attachment path:

const prisma = new PrismaClient();

prisma.$use(async (params, next) => {
    const server = "http://127.0.0.1:5000/api/";

    if (params.model === "Attachment" && params.action === "findMany") {
      // run findMany query
      const result = await next(params);

      // prepend server to thumbnail
      const modified = result.map((res) => ({
        ...res,
        thumbnail: server + res.thumbnail,
      }));

      return modified;
    }

    return next(params);
});

Upvotes: 3

Related Questions