Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example for integrating with Nestjs #386

Open
tl-jarvis-prestidge opened this issue Feb 21, 2020 · 7 comments
Open

Add example for integrating with Nestjs #386

tl-jarvis-prestidge opened this issue Feb 21, 2020 · 7 comments

Comments

@tl-jarvis-prestidge
Copy link

Context

Nestjs is a popular framework for architecting Nodejs backend services. I enjoy working with Nest, just as I do with Nexus / Prisma.

Issue

There's currently no community consensus or integration example for how to use nexus with Nest's flavor of structuring projects.

Nestjs has examples using other code-first approaches in the form of type-graphql.

I would love for the Nexus contributors to tune in a work towards an example or even a first class integration with Nestjs.

@kazazes
Copy link

kazazes commented Apr 13, 2020

+1, but using Nuxt on the frontend here. The two are in a monorepo. While sharing node_module-stored typings is fine while developing, things get tricky when deploying components separately. Adding a common module would be acceptable, technically, but is still a pain.

Enabling multiple output destinations for type generation would be great.

@ZenSoftware
Copy link

I have been digging into how to best go about this myself and have been scratching my head. The best thing I have found thus far is @EndyKaufman / typegraphql-prisma-nestjs. Unfortunately, the repository has not had any commits for the last 4 months, so it is only working with Prisma v2 beta.

I think the largest difference in feature parity between Prisma v1 and Prisma v2 is that Prisma v2 does not support GraphQL schema delegation and prisma-binding anymore. With the last variant of the Nest - Prisma v1 recipe, it leveraged a lot off of the TypeScript code generated prisma-labs/prisma-binding. You could very easily implement schema delegations to the Prisma v1 server from Nest GraphQL. Nest would simply act as a sort of thin gateway layer between your client application and the Prisma v1 server. By simply forwarding the Nest @Args() and @Info() parameters of a GraphQL request to the prisma-binding endpoints, you could get a whole lot of features for free. See the sample code below.

With Prisma v1 schema delegation and prisma-binding you would get the following GraphQL features for free:

  • GraphQL CRUD query/mutations over all Prisma v1 data types
  • GraphQL cursor connections, with cursor + offset pagination, and even aggregation operations
  • GraphQL subscription endpoints on all your Prisma v1 data types to listen in on changes over websockets.
import { UseGuards } from '@nestjs/common';
import { Query, Mutation, Subscription, Resolver, Args, Info } from '@nestjs/graphql';
import { merge } from 'lodash';
import { Roles, GqlGuard, GqlUser, RequestUser } from '../../auth';
import { PrismaService } from '../../prisma';
import { EventTrainerCreateInput, EventTrainerWhereInput, EventTrainerSubscriptionWhereInput } from '../../prisma/binding';

@Resolver('EventTrainer')
@UseGuards(GqlGuard)
@Roles('ADMIN')
export class EventTrainerResolver {
  constructor(private readonly prisma: PrismaService) {}

  @Query()
  @Roles('REGISTERED')
  async eventTrainer(@Args() args, @Info() info) {
    return await this.prisma.binding.query.eventTrainer(args, info);
  }

  @Query()
  @Roles('REGISTERED')
  async eventTrainers(
    @Args() args: { where: EventTrainerWhereInput },
    @Info() info,
    @GqlUser() user: RequestUser
  ) {
    args.where.user = { id: user.id };
    return await this.prisma.binding.query.eventTrainers(args, info);
  }

  @Query()
  @Roles('REGISTERED')
  async eventTrainersConnection(@Args() args, @Info() info) {
    return await this.prisma.binding.query.eventTrainersConnection(args, info);
  }

  @Mutation()
  @Roles('REGISTERED')
  async createEventTrainer(
    @Args() args: { data: EventTrainerCreateInput },
    @Info() info,
    @GqlUser() user: RequestUser
  ) {
    args.data.user = { connect: { id: user.id } };
    return await this.prisma.binding.mutation.createEventTrainer(args, info);
  }

  @Mutation()
  async updateEventTrainer(@Args() args, @Info() info) {
    return await this.prisma.binding.mutation.updateEventTrainer(args, info);
  }

  @Mutation()
  async updateManyEventTrainers(@Args() args, @Info() info) {
    return await this.prisma.binding.mutation.updateManyEventTrainers(args, info);
  }

  @Mutation()
  async upsertEventTrainer(@Args() args, @Info() info) {
    return await this.prisma.binding.mutation.upsertEventTrainer(args, info);
  }

  @Mutation()
  async deleteEventTrainer(@Args() args, @Info() info) {
    return await this.prisma.binding.mutation.deleteEventTrainer(args, info);
  }

  @Mutation()
  async deleteManyEventTrainers(@Args() args, @Info() info) {
    return await this.prisma.binding.mutation.deleteManyEventTrainers(args, info);
  }

  @Subscription('eventTrainer')
  @Roles('REGISTERED')
  async eventTrainerSubscription(
    @Args() args: { where: EventTrainerSubscriptionWhereInput },
    @Info() info,
    @GqlUser() user: RequestUser
  ) {
    merge(args, {
      where: {
        node: {
          user: { id: user.id }
        },
      },
    });

    return this.prisma.binding.subscription.eventTrainer(args, info);
  }
}

Prisma v1 would almost be perfect if it supported case-insensitive text search. It's the only feature for me that would make Prisma v1 the complete GraphQL solution I was hoping it would turn out to be. I am a little sad that the team moved so abruptly to Prisma v2.

Though, at any rate! I was thinking what could be done to achieve something similar is to use a sort of micro-service architecture between Nest and a Nexus+Prisma server. What could be done is you could spin up a Nexus+Prisma server that acts as a standalone GraphQL service, and use Nest as the authentication gateway to forward GraphQL requests to the Nexus+Prisma server, as a sort of replacement to the prisma-binding approach. Since there wont to be any official support for a Nest + Nexus integration, I would really like to hear if anyone has had any success integrating Prisma v2 with Nest.

@EndyKaufman
Copy link

@ZenSoftware I update fork and example 😏

@dvins
Copy link

dvins commented Feb 4, 2021

@ZenSoftware Did you ever manage to get the three to play well together, that is Prisma 2 + Nexus + NestJs? I noticed Nest have published an updated Prisma recipe which uses Prisma 2 and addresses REST.

@ZenSoftware
Copy link

ZenSoftware commented Feb 4, 2021

@dvins Sorry, I was unable to find a way to integrate Nexus non-trivially with Nest. So in my struggles to find a solution to integrate Prisma with Nest, I ended up writing a solution for myself. Nest GraphQL uses Apollo Server under the hood, so it seems to be a much more elegant solution to just code generate the Apollo GraphQL SDL Prisma bindings using Pal.js written by @AhmedElywa. If you don't want to go through the process of manually integrating Apollo GraphQL SDL Prisma bindings into your stack yourself, you can use my starter kit in the link below that has everything pre-integrated. The starter kit code generates everything from the schema.prisma file. It code generates the Nest GraphQL endpoints to hook into Prisma Client, and also the Apollo Angular services for type safe access to the Nest GraphQL API. At minimum, it should give you an idea of how to create a Nest GraphQL gateway to Prisma Client.

🎐 Cheers my friend. ^_^

⛩ Zen ⛩ Nest + Prisma + Angular 🏮 Full Stack Starter Kit

@djedlajn
Copy link

djedlajn commented Feb 7, 2021

@dvins Sorry, I was unable to find a way to integrate Nexus non-trivially with Nest. So in my struggles to find a solution to integrate Prisma with Nest, I ended up writing a solution for myself. Nest GraphQL uses Apollo Server under the hood, so it seems to be a much more elegant solution to just code generate the Apollo GraphQL SDL Prisma bindings using Pal.js written by @AhmedElywa. If you don't want to go through the process of manually integrating Apollo GraphQL SDL Prisma bindings into your stack yourself, you can use my starter kit in the link below that has everything pre-integrated. The starter kit code generates everything from the schema.prisma file. It code generates the Nest GraphQL endpoints to hook into Prisma Client, and also the Apollo Angular services for type safe access to the Nest GraphQL API. At minimum, it should give you an idea of how to create a Nest GraphQL gateway to Prisma Client.

🎐 Cheers my friend. ^_^

⛩ Zen ⛩ Nest + Prisma + Angular 🏮 Full Stack Starter Kit

Well done awesome, repo.

@ceefour
Copy link

ceefour commented Mar 13, 2021

shinto_shrine Zen shinto_shrine Nest + Prisma + Angular izakaya_lantern Full Stack Starter Kit

Thank you @ZenSoftware , this is very interesting approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants