graphql-nexus / nexus

Code-First, Type-Safe, GraphQL Schema Construction
https://nexusjs.org
MIT License
3.4k stars 274 forks source link

Announcing Nexus Framework Transition #373

Closed jasonkuhrt closed 4 years ago

jasonkuhrt commented 4 years ago

For users coming to this now please see the unframework annoucement.

🚧 🚧 🚧 🚧 🚧 🚧


TLDR

Nexus is becoming an opinionated backend application framework for building GraphQL APIs in TypeScript and Node.js:

The current state

GraphQL Nexus today is a library that lets developers build GraphQL schemas in a code-first way. In that sense, it is similar to libraries like graphql-js and TypeGraphQL as well as SDL-first approaches such as graphql-tools. Nexus was originally built by Tim Griesser. Recently, Jason Kuhrt and Flavian Desverne from the Prisma Labs team have joined the development and maintenance efforts as well.

What's changing?

Nexus is changing from a library with a single responsibility ("building GraphQL schemas") to a fully-fledged API framework, including a pluggable database. This means that in the future the nexus package will not only contain functionality to build GraphQL schemas, but also connect to a database, generate CRUD resolvers, enable authentication and authorization, and more: features developers need for building backend applications. As mentioned before, if you don't want to buy into this new framework, you'll be able to keep using the pure schema building functionality of present-Nexus through the @nexus/schema package.

New GitHub organization: graphql-nexus

All repositories that are related to the new Nexus framework will be hosted under the graphql-nexus GitHub organization. Tim Griesser, Jason Kuhrt, and Flavian Desverne will be the official org admins.

New npm scope @nexus

Certain Nexus framework components will be available under the @nexus npm scope. Tim Griesser, Jason Kuhrt, and Flavian Desverne will again be admins here.

Componentizing Nexus

Generally, it is envisioned framework components will be modular and available under the @nexus scope/namespace.

The first example of this will be the @nexus/schema package (mentioned above). A second may be the Nexus framework logger which currently lives in core (it may be extracted to a completely independent npm package though).

Plugings and ecosystem

The Nexus framework will have a deep plugin system for you to extend its functionality with custom logic and features. The first major plugin helping guide the plugin system capabilities is the Prisma plugin which the Prisma Labs team is also actively working on.

The package name of a plugin must be prefixed with nexus-plugin-. For example, the current nexus-prisma package has a framework counterpart of nexus-plugin-prisma. A plugin that enables authentication via Auth0 might be called nexus-plugin-auth0.

nexus-prisma

The present nexus-prisma functionality will move to nexus-plugin-prisma package under the schema module. This matters for you if you want to stick with @nexus/schema. Then you will need to use the Nexus schema Prisma plugin rather than the Nexus framework Prisma plugin. This will be available as a module in the framework plugin package. So it will look something like (still tbd):

import * as Nexus from '@nexus/schema'
import { nexusPrismaPlugin } from 'nexus-plugin-prisma/schema'

Nexus.makeSchema({
 plugins: [nexusPrismaPlugin()]
 // ...
})

It is expected that working with schema component and its plugins directly will become largely for low-level work like integrations with other tools or advanced users doing highly custom stuff.

Versioning Plan

The migration is planned for minimum disruption as follows:

For nexus-prisma users:

GitHub repo naming changes overview

Current repo name Future repo name
github.com/graphql-nexus/nexus-future github.com/graphql-nexus/nexus
github.com/prisma-labs/nexus github.com/graphql-nexus/schema
github.com/prisma-labs/nexus-prisma github.com/graphql-nexus/nexus-plugin-prisma

npm package naming changes overview

Current package name Future package name
nexus @nexus/schema
nexus-future nexus
nexus-prisma nexus-plugin-prisma (/schema)

When will this happen

Much of the underlying transition is ready to try out now but we will gather feedback before doing the last top-level changes. We hope to have this transition completed in a matter of weeks. Your feedback is a key step now.

Should I migrate to the framework?

Our aim is to have a stable set of basic framework features by the end of the quarter (March 31). You can try it out today but it is not ready for production yet.

The intention is not to force anyone to migrate to the framework and we are dedicated to its modular component architecture. @nexus/schema is here to stay.

Of course we hope you're as excited about the framework as we are, and look forward to all and any feedback you have once you've had a chance to try it out!

beeplin commented 4 years ago

So actually graphql-santa is turning into the new nexus, right? ;)

jasonkuhrt commented 4 years ago

@beeplin correct! :)

kitze commented 4 years ago

Looking forward to this.

Nayni commented 4 years ago

What will happen to the already built-in plugins of the current nexus state (such as the authorize plugin and the more recent connections plugin)?

Am I correct to expect them to ship and/or work with the new @nexus/schema package?

jasonkuhrt commented 4 years ago

Hey @Nayni

Am I correct to expect them to ship and/or work with the new @nexus/schema package?

Yes

What will happen to the already built-in plugins of the current nexus state (such as the authorize plugin and the more recent connections plugin)?

Generally speaking:

This multi-plane plugin architecture is certainly unusual and quite arguably incidental rather than by design. Yet the system is not incoherent either. There is a clean super/sub-set relationship going on. We just have to wrangle the tooling/workflow/ecosystem well enough that it doesn't become a mess/confusing.

huv1k commented 4 years ago

I am really looking forward. I have two questions about plugins:

  1. Why all plugins need to be prefixed with nexus-plugin- It's because of plugin loader or discoverability?
  2. What kind of plugins going to be possible with a new release?
jasonkuhrt commented 4 years ago

Hey @huv1k

Why all plugins need to be prefixed with nexus-plugin-

Yep loading and discovery but more too. We are going to be building a lot of tooling around this pattern such that within the framework and CLI, the pedantic prefix should essentially never have to be seen/experienced by a developer.

What kind of plugins going to be possible with a new release?

Quite a lot. Still under development. There are currently three dimensions we already have implemented to a degree: "worktime", "runtime", "testtime".

Just to give a sense:

Worktime encompasses CLI workflows like dev mode enhancements. Runtime encompasses things like what schema plugins do. Testtime encompasses things like mocking, spawning a test server, integration test db setup/teardown, integration with different test runners, ...

But if the framework is still under development you can think of the plugin system being twice as much so, which kind of makes sense since the plugin system has its own complexity plus inheriting the instability of its host/target (the framework).

benawad commented 4 years ago

How does Yoga 2 fit into this?

Is this the evolution of it? Will it use Yoga 2? Is this an alternative to Yoga 2?

jasonkuhrt commented 4 years ago

Hey @benawad

Is this the evolution of it?

Spiritually yes

Will it use Yoga 2?

No (for server, it currently uses graphql-js under the hood)

Is this an alternative to Yoga 2?

Probably stronger than "alternative" seeing as Yoga 2 isn't actively developed and thus isn't a viable long-term/production choice in its own right.

benawad commented 4 years ago

including a pluggable database. This means that in the future the nexus package will not only contain functionality to build GraphQL schemas, but also connect to a database, generate CRUD resolvers

So is nexus going to build it's own database adapter/ORM or will it be leveraging an existing database adapter and scaffolding things kind of like https://github.com/Urigo/graphql-cli

jasonkuhrt commented 4 years ago

So is nexus going to build it's own database adapter/ORM

No, the core will never force an orm solution.

The core has only the responsibility to make the pluggable db system have granular enough extension points with appropriate semantics.

or will it be leveraging an existing database adapter and scaffolding

Not exactly an answer but related enough I think:

The Prisma Labs team whom make up 2/3 of the core Nexus team are also working on the nexus-plugin-prisma.

Our plan is that Nexus will always have a great ORM option via Prisma. But we're doing it in a completely decoupled, plugged in, manner. Presumably, surely, the community will create other Nexus database plugins ("db drivers" as we sometimes refer to them...).

Nayni commented 4 years ago

This will soon be explored manually with nexus-plugin-prisma where schema-only plugin will be available at nexus-plugin-prisma/schema. We think a strong convention like this could help avoid community fragmentation. Of course this does not address case of plugins that are only schema level. Again we'll see how this goes.

I really hope you'll be able to safeguard this because currently I'm a little skeptical on this part.

I've personally been a big fan of nexus since it first came out. It solved a single problem I was having really well:

I think the plugin system that @tgriesser built out has also enforced this vision. It gave me, the developer, some control back on what nexus was doing internally and helped me customize small parts of my workflow. I think the two built-in plugins are a great example of this:

There is also a lot more potential of such plugins for just the schema building focus alone. A few that have been on the roadmap and some that me and my team have been thinking about are:

In my opinion these are all features which I would like to find (or build) in the schema building part of nexus (and maybe they can be enhanced at framework level, but I feel like I shouldn't be forced to buy into the framework just to have these features in my schema).

Maybe it could be an option to not use the concept of a plugin on both levels. But instead call them something semantically different. The schema building part could have plugins while the framework can have adapters (I'm just coining a name here). That way a feature like nexus-prisma can still ship as one package but you would use the plugin and the adapter semantically different:

import nexusPrismaAdapter from "nexus-adapter-prisma";
import Framework from "nexus";

Framework.addAdapter(nexusPrismaAdapter());
import { nexusPrismaPlugin } from "nexus-adapter-prisma/plugin";
import { makeSchema } from "@nexus/schema";

makeSchema({
  plugins: [nexusPrismaPlugin()]
}); 

You could sort of compare this as you can have a eslint-plugin which adds new rules and you have a eslint-preset that can configure these rules for you.

Regardless, I think it's great that there is a roadmap to build high levels of abstractions on top of this already great core which nexus is today. I just hope that by merging the names it doesn't become a must buy into everything solution because at least for me that's been the great part of nexus today. It's a drop in replacement for that one thing which I wanted to fix, building schemas.

tre-dev commented 4 years ago

Thanks for the work, Jason & co! I also agree with @Nayni and hope that advanced features for @nexus/schema are not going to be put too much behind. For example, it would be really helpful to have a default plugin for argument validation (like joi).

Because, right now, I'm already using graphql-nexus with prisma2 (postgres), redis & dynamodb quite smoothly and for me, the biggest pain point isn't really the integration but rather some missing features around the classic graphql-nexus. (i.e argument validation)

Maybe I'm missing the grand vision of the framework and everything makes sense once it's here, but for now, my concern is that if you try to make it right for everyone, in the end, the tools might not sophisticated enough.

I know, in the beginning, it's always nice to have a lower entry barrier, but every time I migrate away from complete packages (i.e. graphql yoga, apollo-boost, ..), I get reminded that it has some major upsides not being depended on bundles.

TL;DR: Please put the same empathise on improving the modular building blocks of nexus (i.e. schema) as you're putting into building this whole framework.

Thank you!

momakes3 commented 4 years ago

Keep it up folks πŸ‘ The guides for upgrading/migrating will be very valuable for bringing early users from your existing userbase. (please link to them everywhere once ready haha)

I quite like the categorization of the documentation, I can pick which parts I need and read those.

2color commented 4 years ago

All looking great. Excited to see this shaping up.

For some inspiration on the topic of plugins, I can highly vouch for Hapi's plugin system.

Screenshot 2020-02-10 at 10 30 09

Plugin dependencies β€” plugins can safely rely on other plugins, including the order in which they must be execute, no matter the order in which you register them.

As an example, feel free to check out how the code is organised in https://github.com/aragonone/notification-service/blob/master/lib/plugins/account.js.

In my experience, Hapi's plugin system is a great way to have the framework deal with resolving dependencies (by building a dependency graph) and injecting so you don't have to deal with singletons and weird imports all over the place.

tgriesser commented 4 years ago

I just hope that by merging the names it doesn't become a must buy into everything solution because at least for me that's been the great part of nexus today. It's a drop in replacement for that one thing which I wanted to fix, building schemas.

It won't, the core will always stay separate, the only change will be nexus -> @nexus/schema in the import statements and package.json.

This is actually one of my main sticking points - this originally of stemmed from a desire to make Nexus (core) do more than I believed it should. A goal of mine from the beginning with the project was to have graphql as the sole dependency of the project and I'd like to stick as close to that as possible.

I understand the desire to add more to the framework, especially after watching some of what can be done in terms of DX in the videos at https://nexus-future.now.sh/#/README, which is why I'm on board with moving the core (current package) to @nexus/schema, and then having other pieces that layer on top of it and create a more opinionated framework.

Of course, since Prisma is helping support it, I also don't mind if there is built in abstractions for their database layer, but the main takeaway is it won't be mixed in with the core, which should just be for schema generation.

I really hope you'll be able to safeguard this because currently I'm a little skeptical on this part.

This is something I will make a goal to try and see happen, since I agree with the sentiment.

Maybe it could be an option to not use the concept of a plugin on both levels. But instead call them something semantically different. The schema building part could have plugins while the framework can have adapters (I'm just coining a name here). That way a feature like nexus-prisma can still ship as one package but you would use the plugin and the adapter semantically different:

I think this is a may work, will discuss with @Weakky and @jasonkuhrt, rather than trying to overload the plugin term, to create something separate, there are plenty of words that can be used here, I'm sure we can come up with something.

For some inspiration on the topic of plugins, I can highly vouch for Hapi's plugin system.

I too think Hapi's project structure of having multiple independent components which are composable together into a framework is a nice model to follow, though I think there's something missing in terms of a great out-of-the box experience with hapi for the 90% use case that a nexus framework could potentially do really nicely.

jasonkuhrt commented 4 years ago

A migration guide has been started.

fullStackDataSolutions commented 4 years ago

This looks awesome I love Nexus. Is there support to pass through a client created with the GraphCLI in the same way you can pass through data from Prisma?

For example:

const Query = prismaObjectType({
  name: "Query",
  definition(t) {
    t.prismaFields(["*"]);
  }
});
jasonkuhrt commented 4 years ago

Hey @blazestudios23, I'm not sure I understand what GraphCLI is? Also your reference is how nexus-prisma for Prisma 1 worked, not for Prisma 2 (but I get your gist about the passthrough!).

Maybe you want to create a new issue and we can discuss further?

jagreehal commented 4 years ago

So just to clarify I use Next.js, Apollo and Nexus (pretty much like this https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-micro) and use makeSchema from 'nexus'

Will I still have the ability to use nexus to do type first GraphQL and call makeSchema?

Or will nexus will only work by using server from 'nexus-future'?

jasonkuhrt commented 4 years ago

Hey @jagreehal

Will I still have the ability to use nexus to do type first GraphQL and call makeSchema?

Yeah, you will just use @nexus/schema.

Or will nexus will only work by using server from 'nexus-future'?

The server component is still under development. How integration looks like with Next.js is something we might focus on in Q2. It is possible today to augment or swap the server. But integrating two frameworks together will naturally require more than that.

chanlito commented 4 years ago

Hey @jasonkuhrt module nexus-plugin-prisma/schema not found. Has it been published?

and using this import { nexusPrismaPlugin } from 'nexus-prisma'; conflict types with @nexus/schema

jasonkuhrt commented 4 years ago

Hey @jasonkuhrt module nexus-plugin-prisma/schema not found. Has it been published?

Hey @chanlito this part of the transition has not been done yet. You can continue to use nexus-prisma for now.

and using this import { nexusPrismaPlugin } from 'nexus-prisma'; conflict types with @nexus/schema

Could you open an issue on nexus-prisma about that? Sounds like a bug.

jasonkuhrt commented 4 years ago

Hey everyone, we have an update about timelines regarding:

  • No exact date is set for the final switchover yet

Our target date is Monday March 30. That is a little under two weeks from now. Between now and then we'll be rolling out docs and tweaks that make transition as smooth as we can make it. We will continue of course to improve the framework where it lags behind manual schema component usage and app needs. Removing blockers to adoption will remain one of our focuses over the coming weeks.

Feedback and questions welcome, as always!

jasonkuhrt commented 4 years ago

Hey everyone, things are underway. We will work with a few pre-releases before finally cutting 0.20.0. The easiest way to try this out is by installing nexus@next. The will make the final 0.20 release in the coming week or two. The things we want to try to resolve first are:

We will close this issue once 0.20.0 has been cut.

jasonkuhrt commented 4 years ago

We have made significant progress on some key elements of the plugin system, and docker support turned out to be a non-issue. Windows support is still lacking but we have, anyways, cut 0.20.0 and will iterate forward on that.

Thanks everyone, excited to progress together.

macrozone commented 4 years ago

Hey @jagreehal

Will I still have the ability to use nexus to do type first GraphQL and call makeSchema?

Yeah, you will just use @nexus/schema.

Or will nexus will only work by using server from 'nexus-future'?

The server component is still under development. How integration looks like with Next.js is something we might focus on in Q2. It is possible today to augment or swap the server. But integrating two frameworks together will naturally require more than that.

We use @nexus/schema with prisma a lot in next.js project lately, because it gives you a nice fullstack app in one project, which is very handy for many projects.

while @nexus/schema as a library naturally works with next.js in api-routes, this is probably not the case for nexus-framework. So i hope that you don't lock out non-framework users in the future

jasonkuhrt commented 4 years ago

Next.js example with nexus here: https://github.com/graphql-nexus/examples#nextjs. Some caveats but works.

macrozone commented 4 years ago

@jasonkuhrt thank you. We used just @nexus/schema without nexus framework and this worked without these caveats. Only downside is the additional boilerplate. What would we additionally gain from using nexus framework?

jasonkuhrt commented 4 years ago

@macrozone published this https://nexusjs.org/adoption-guides/nexus-schema-users, hope it helps. We'll continue to flush out that page with content. Your question comes up often.

macrozone commented 4 years ago

@jasonkuhrt this explains a lot, very well done!

I hope we can migrate all our project to framework soon

jasonkuhrt commented 3 years ago

For users coming to this now please see the unframework annoucement