Thoughts on Prisma-Nexus?


#1

Hey all

So by now you have probably read this article, introducing us to Prisma Nexus.
I wanted to take a chance to ask the community about their first reaction?
Does this look like the way to go? Why? Why not?

I’ll start by sharing my own first impressions, keep in mind this is just from reading the article and docs, not from actual use!

Pros of the Code-First approach:

  • All the code in one place. You define your object and it’s resolvers in the same place.
  • Abillity to dynamically generate your api.

Pros of the SDL-first approach:

  • Less clutter in the SDL. Makes your schema easier to reason with.
  • Easier to make your api be a simple layer over an existing graphql api.

This last point is very big plus for me. With the SDL first approach, you can easily import your whole schema from a file generated from an existing graphql api, and then overwrite what needs be. I’ve found this to be very fast.

Lets say I want to make a simple change to an existing datamodel: add an email field to an existing User type

type User {
  id: ID! @unique
  username: String! @unique
  email: String @unique # we want to add this field
}

With the current SDL-first aproach this is very simple

  1. Add the field to the User type in the prisma datamodel
  2. Run prisma deploy
  3. Run prisma generate

Done!
Since we import our schema from the generated file, we do not have to worry about adding that field to the relevant types. Granted, it can be more complex (maybe we redefined the User type to hide a password field? In that case we only need to worry about the object type, not the input types).

Now lets take a look at the steps needed to apply the same change in a nexus powered API:

  1. Add the field to the User type in the prisma datamodel
  2. Run prisma deploy
  3. Add the field to the User type
  4. Add the field to the UserCreateInput type
  5. Add the field to the UserUpdateInput type
  6. Add the field to the UserWhereInput type
  7. Add the field to the UserWhereUniqueInput type
  8. Add the field to the UserOrderByInput type
  9. I’m forgetting about subscriptions…

As you can see that’s a lot more steps. So many more chances to make mistakes.

This graphic is from the prisma documentation and shows how prisma expands your data model into multiple types.

With Nexus, it seems like I would need to redefine each and everyone of those types. So I’m not managing two different but related versions of my schema: the database layer (prisma) and the business layer (nexus). The fact those two are in completely different formats makes things harder to understand and compare.

Conclusion

I’ve become a big fan of the “trim the bad parts” approach the SDL-first approach has allowed me. I’m pretty sure that approach is not feasible with Nexus, but I know the documentation is probably incomplete, so I’m wondering if I’m missing something?

What about you? What do you think?


#2

Are you aware of nexus-prisma?

This plugin allows type safe prisma bindings like features like one line to expose mutations and fields.

Looks like you are using Nexus without it and surely that would be a great overhead that way you


#3

Nexus-Prisma does seem to be the missing piece. That said: is it JS compatible? or is this TS only?


#4

It is fully JS/TS compatible. But I will still recommend generation types to get great autocompletion in vscode


#5

I have not made the transition to TS yet, and am only able to generate .ts files from nexus-prisma.

aparently the nexus-prisma-generate command can take a js argument to generate the js version :slight_smile:


#6

Update

Last night I tried nexus and got it working

Unfortunately it feels like a step back and reminds me a lot of the reference graphql implementation: too verbose, too cluttered. Compare the following, equivalent code:

input AuthenticationInput {
  username: String!
  password: String!
}
export const AuthenticationInput = inputObjectType({
  name: 'AuthenticationInput',
  definition (t) {
    t.string('username', { required: true })
    t.string('password', { required: true})
  }
})

This example is very small but I simply find the first approach to be easier to reason with.

I will be watching nexus but for now I will stick to the SDL first approach.

Cheers!


#7

I am completely with you in your analysis. I’ve written GraphQL servers in “code-first” regimes (Elixir), but I prefer SDL-first development for many of the reasons you cited.

The biggest SDL pain point remains standardized imports, but I’ll take that pain for something that’s much easier to reason about.