Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

Nuxt 3 nitro + mikro-orm #5603

Closed
max5432112345 opened this issue Jun 24, 2022 · 5 comments
Closed

Nuxt 3 nitro + mikro-orm #5603

max5432112345 opened this issue Jun 24, 2022 · 5 comments

Comments

@max5432112345
Copy link

max5432112345 commented Jun 24, 2022

Environment

  • Operating System: Linux
  • Node Version: v16.15.1
  • Nuxt Version: 3.0.0-rc.4
  • Package Manager: [email protected]
  • Builder: vite
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Reproduction

import { RequestContext } from '@mikro-orm/core'

import { DI } from '../data-source'

export default defineEventHandler(async (event) => {
  console.log(next)
  RequestContext.create(DI.orm.em, next) // no next function
})

OR

import { RequestContext } from '@mikro-orm/core'

import { DI } from '../data-source'

export default (req, res, next) => {
  console.log(next)
  RequestContext.create(DI.orm.em, next) // has next but not work, such error was with fastify https://github.com/fastify/fastify/issues/3570
}

DI file

import 'reflect-metadata'
import {
  // EntityManager,
  // EntityRepository,
  MikroORM
} from '@mikro-orm/core'

import { Author } from './entities'

export const DI = {} as {
  orm: MikroORM,
  // em: EntityManager,
  // authorRepository: EntityRepository<Author>
}

(async () => {
  DI.orm = await MikroORM.init({
    type: 'mariadb',
    entities: [Author],
    dbName: 'nuxt',
    password: '123456',
    user: 'admin',
    debug: true
  })
})()

Describe the bug

No next function. In legacy exist but no effect like with old version of fastify here
nestjs/nest#8837
nodejs/node#41285

[nitro] [dev] [unhandledRejection] ValidationError: Using global EntityManager instance methods for context specific actions is disallowed. If you need to work with the global instance's identity map, use allowGlobalContext configuration option or fork() instead.

Additional context

No response

Logs

No response

@max5432112345
Copy link
Author

max5432112345 commented Jun 24, 2022

some file can be taken from https://github.com/max5432112345/nuxt-mikro

@max5432112345
Copy link
Author

need useNext() helper???

@max5432112345
Copy link
Author

@beyer-johannes
Copy link

+1 Stuck at this too

@beyer-johannes
Copy link

@max5432112345 here a approach that works for me, but is defenitly not the end-solution:

Create a server middleware with following content which initialize the database connection if no one exists:

import { RequestContext } from '@mikro-orm/core'
import { useClient } from '../datasources/tenant/client'

export default defineEventHandler(async (event) => {
  const client = await useClient();

  // TODO:: https://github.com/nuxt/framework/issues/5603
  RequestContext.create(client.orm.em, () => { })

  event.context.tenantClient = client;
})

A client file:

import type { MySqlDriver } from '@mikro-orm/mysql';
import { MikroORM, EntityRepository, EntityManager } from "@mikro-orm/core";
import { Author, Book, BookTag, Publisher, BaseEntity } from "./entities";
import { SqlHighlighter } from "@mikro-orm/sql-highlighter";

export type Client = {
    orm: MikroORM,
    em: EntityManager,
    authorRepository: EntityRepository<Author>
};

let client: Client;

export const useClient = async () => {
    if (!client) {
        // TODO:: CLI config will be used automatically
        const orm = await MikroORM.init<MySqlDriver>({
            dbName: "mikro-orm",
            type: "mysql",
            host: process.env.MYSQL_HOST || "127.0.0.1",
            port: Number(process.env.MYSQL_PORT) || 3306,
            user: process.env.MYSQL_USERNAME || "root",
            password: process.env.MYSQL_PASSWORD || "root",
            // as we are using class references here, we don't need to specify `entitiesTs` option
            entities: [Author, Book, BookTag, Publisher, BaseEntity],
            highlighter: new SqlHighlighter(),
            discovery: { disableDynamicFileAccess: true },
            debug: true, // todo:: env
        });
        const em = orm.em.fork();
        const authorRepository = em.getRepository(Author);

        client = {
            orm, em, authorRepository
        };
    }

    return client;
}

Now you can use in your /api/foo.ts api endpoint the client (orm) as following:

import { QueryOrder } from "@mikro-orm/core";
import { Client } from "../datasources/tenant/client";

export default defineEventHandler(async (event) => {
    const { tenantClient } = event.context as { tenantClient: Client };

    const authors = await tenantClient.authorRepository.findAll({
        populate: ['books'],
        orderBy: { name: QueryOrder.DESC },
        limit: 20,
    });

    return {
        statusCode: 200,
        body: JSON.stringify(authors),
    };
});

Hope it helps you a bit

@nuxt nuxt locked and limited conversation to collaborators Jul 27, 2022
@danielroe danielroe converted this issue into a discussion Jul 27, 2022
@danielroe danielroe added the 3.x label Jan 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants