Skip to content

Instantly share code, notes, and snippets.

@1isten
Last active January 23, 2023 02:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save 1isten/ed286c3980523f4a4f9b6b627f540091 to your computer and use it in GitHub Desktop.
Save 1isten/ed286c3980523f4a4f9b6b627f540091 to your computer and use it in GitHub Desktop.
Nuxt + Next: run Next.js as a server (connect) middleware on Nuxt.js (v2)
  1. Do not start Nest server, instead, just export an async function which returns its initialized app instance:
// path/to/nest/src/main.ts

import { NestFactory } from '@nestjs/core';
import { ExpressAdapter, NestExpressApplication } from '@nestjs/platform-express'; // Optional because the `@nestjs/platform-express` package is used by default
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule); // Optionally, `const app = await NestFactory.create<NestExpressApplication>(AppModule, new ExpressAdapter());`
  await app.init();

  return app.getHttpAdapter().getInstance();
}

export default bootstrap;
  1. Nuxt's built-in server uses connect to form its middleware stack. Beacuse the Nest (express) instance returned by the bootstrap function above is compatible with connect/express, we can use is just like a normal middleware:
// path/to/nuxt/nuxt.config.js

import bootstrap from 'path/to/nest/dist/main.js'; // import the compiled JS (do not import TS)

export default async () => ({
  // ...

  serverMiddleware: [
    {
      path: '/api',
      handler: await bootstrap(), // use nest app instance as a normal nuxt server middleware
    }
  ],
});

That's it.

Start the Nuxt app and we can see the Nest API response at: localhost:3000/api

@1isten
Copy link
Author

1isten commented Apr 17, 2021

✨ Bonus: Nuxt + Nest (Fastify version)

// path/to/nest/src/main.ts

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; // npm i --save @nestjs/platform-fastify
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter({ ignoreTrailingSlash: true, logger: true }));
  await app.init();

  const fastify = app.getHttpAdapter().getInstance();
  await fastify.ready();

  // Unlike the Express version which the app instance itself is a handler function, the fastify instance is an object
  // we have to return a handler function for Nuxt serverMiddleware
  return function (req, res) {
    fastify.server.emit('request', req, res);
  };
}

export default bootstrap;

Credit: @ekoeryanto's comment ♥️

@1isten
Copy link
Author

1isten commented Apr 17, 2021

For reference:

  • pure express
function bootstrap() {
  const app = require('express')();

  app.get('/', (req, res) => {
    res.status(200).send({
      hello: 'express',
    });
  });

  return app;
}

export default bootstrap;
  • pure fastify
async function bootstrap() {
  const fastify = require('fastify')({ ignoreTrailingSlash: true, logger: true });

  fastify.get('/', (req, res) => {
    return {
      hello: 'fastify',
    };
  });

  await fastify.ready();

  return function (req, res) {
    fastify.server.emit('request', req, res);
  };
}

export default bootstrap;

@1isten
Copy link
Author

1isten commented Apr 17, 2021

  • pure koa
function bootstrap() {
  const Koa = require('koa');
  const Router = require('@koa/router');

  const app = new Koa();
  const router = new Router();

  router.get('/', (ctx, next) => {
    // ctx.status = 200;
    // ctx.type = 'application/json';
    ctx.body = {
      hello: 'koa',
    };
  });

  app.use(router.routes()).use(router.allowedMethods());

  return app.callback(); // return the callback
}

export default bootstrap;

Credit: @Atinux's comment ♥️

@n4an
Copy link

n4an commented Sep 18, 2021

Something not work

If to main.ts from this example to add any database orm (sequalize/prisma/typeorm)

Prism controller from https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nestjs
import {
Controller,
Get,
Param
// Post,
// Body,
// Put,
// Delete,
// Query
} from '@nestjs/common'
import {
// User as UserModel,
Post as PostModel
// Prisma
} from '@prisma/client'
import { AppService } from './app.service'
@controller()
export class AppController {
// eslint-disable-next-line no-useless-constructor
constructor (private readonly prismaService: AppService) {}

@Get('post/:id')
async getPostById (@Param('id') id: string): Promise<PostModel> {
  return await this.prismaService.post.findUnique({ where: { id: Number(id) } })
}

get an error:

ERROR [ExceptionsHandler] Cannot read property 'post' of undefined TypeError: Cannot read property 'post' of undefined

Sequalize controller from https://github.com/nestjs/nest/tree/master/sample
import { Body, Controller, Delete, Get, Param, Post } from '@nestjs/common'
import { CreateUserDto } from './dto/create-user.dto'
import { User } from './user.model'
import { UsersService } from './users.service'

@Controller('users')
export class UsersController {
  // eslint-disable-next-line no-useless-constructor
  constructor (private readonly usersService: UsersService) {}

  @Post()
  create (@Body() createUserDto: CreateUserDto): Promise<User> {
    return this.usersService.create(createUserDto)
  }

ERROR [ExceptionsHandler] Cannot read property 'findOne' of undefined TypeError: Cannot read property 'findOne' of undefined

Main.ts from

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; // npm i --save @nestjs/platform-fastify
import { AppModule } from './app.module';

async function bootstrap() {
const app = await NestFactory.create(AppModule, new FastifyAdapter({ ignoreTrailingSlash: true, logger: true }));
await app.init();

const fastify = app.getHttpAdapter().getInstance();
await fastify.ready();

// Unlike the Express version which the app instance itself is a handler function, the fastify instance is an object
// we have to return a handler function for Nuxt serverMiddleware
return function (req, res) {
  fastify.server.emit('request', req, res);
};

}

export default bootstrap;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment