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

Announcing Nexus Framework Transition #373

Closed
jasonkuhrt opened this issue Feb 5, 2020 · 32 comments
Closed

Announcing Nexus Framework Transition #373

jasonkuhrt opened this issue Feb 5, 2020 · 32 comments
Labels
type/discussion Discussion about proposals, etc.

Comments

@jasonkuhrt
Copy link
Contributor

jasonkuhrt commented Feb 5, 2020

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 nexus functionality will move to @nexus/schema. Use this if you just want Nexus' GraphQL schema building features
  • The current nexus package will become the primary package of the future Nexus framework.
  • You can explore the current state of the future Nexus framework right now in the nexus-future package and at website https://nexusjs.org.
  • No exact date is set for the final switchover yet
    Monday March 30
  • There is a migration guide

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:

  • A 0.12.0 release of present nexus with post-install notice to transition to @nexus/schema@0.12.0
  • A 0.20.0 release of nexus which will be the framework from then on
  • Docs on how to migrate from Nexus present to Nexus the framework
  • Docs on how to migrate from Nexus present to @nexus/schema (very little to do!)
  • https://nexus.js.org will go offline once its content has migrated to https://nexusjs.org

For nexus-prisma users:

  • A 0.10.0 release of nexus-prisma with post-install notice to transition to nexus-plugin-prisma/schema

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!

@jasonkuhrt jasonkuhrt added the type/discussion Discussion about proposals, etc. label Feb 5, 2020
@jasonkuhrt jasonkuhrt pinned this issue Feb 5, 2020
@beeplin
Copy link

beeplin commented Feb 6, 2020

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

@jasonkuhrt
Copy link
Contributor Author

@beeplin correct! :)

@kitze
Copy link

kitze commented Feb 6, 2020

Looking forward to this.

@Nayni
Copy link
Contributor

Nayni commented Feb 6, 2020

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
Copy link
Contributor Author

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:

  • Sometimes automatic integration, for example connection plugin is effectively a core concept of the framework.
  • They are not being killed or like, but we do want framework users to not have to know about them as well. We think schema component and schema plugins will be lower-level and for more advanced/custom users/use-cases long-term. We'll see how this goes.
  • In a framework project, they will still be directly consumable, if user really needs it
  • In the website/docs, they will be thoroughly documented in the context of framework plugins. We will make it clear that that part of the plugin system is decoupled and show or reference how to ship schema-only plugins
  • We are considering first-class tooling support for building plugins that gracefully decompose to schema-only usage. 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.

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
Copy link
Contributor

huv1k commented Feb 7, 2020

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
Copy link
Contributor Author

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
Copy link

benawad commented Feb 7, 2020

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
Copy link
Contributor Author

jasonkuhrt commented Feb 7, 2020

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
Copy link

benawad commented Feb 7, 2020

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
Copy link
Contributor Author

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
Copy link
Contributor

Nayni commented Feb 7, 2020

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:

  • It helps me build GraphQL Schemas. Type-safe, fast and in a flavor I had sort of forgotten: code first.

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:

  • The authorize plugin adds authentication to my workflow
  • The connections plugin gives me relay connections out of the box so I don't have to repeat myself.

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:

  • Query Complexity
  • Argument Validation (with joi-like integration)
  • Logging / Tracing enhancements
  • Visibility / Scoping

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
Copy link

tre-dev commented Feb 8, 2020

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
Copy link

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
Copy link

2color commented Feb 10, 2020

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
Copy link
Member

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
Copy link
Contributor Author

jasonkuhrt commented Feb 18, 2020

A migration guide has been started.

jasonkuhrt referenced this issue Feb 18, 2020
This supports the transition prisma-labs/graphql-framework-experiment#373. It allows the @nexus/schema package to not have to branch code from nexus package.
jasonkuhrt referenced this issue Feb 18, 2020
This supports the transition prisma-labs/graphql-framework-experiment#373. It allows the @nexus/schema package to not have to branch code from nexus package.
jasonkuhrt referenced this issue in graphql-nexus/nexus-plugin-prisma Feb 21, 2020
This is to support the nexus transition prisma-labs/graphql-framework-experiment#373. Nexus 0.12.0-rc.13 includes a typegen feature that makes it work even
after the package rename to @nexus/schema

BREAKING CHANGE:

- Installs will now receive warnings when depending on versions of nexus
  less than 0.12.0-rc.13.
@fullStackDataSolutions
Copy link

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
Copy link
Contributor Author

jasonkuhrt commented Mar 6, 2020

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
Copy link

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
Copy link
Contributor Author

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
Copy link

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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.

lolopinto added a commit to lolopinto/ent that referenced this issue May 9, 2020
it's too early. i'm not sure i can build on this yet

examples literally changed from one day to the other with the migration to a "framework". i can't figure out how to do a simple use case
framework transition: graphql-nexus/nexus#373

may be tied to much to prisma? or too much to deploying quickly without even showing how to test

and I couldn't get this simple case to work

looks like i could have tried to continue with @nexus/schema but just not the right timing

error message from building

     TS2322: Type '(root: {}, args: { name?: string | null | undefined; status?: string | null | undefined; }, ctx: any, info: GraphQLResolveInfo) => User' is not assignable to type 'FieldResolver<"Query", "user">'.
  Type 'User' is not assignable to type '{ emailAddress: string; firstName: string; id: string; lastName: string; } | PromiseLike<{ emailAddress: string; firstName: string; id: string; lastName: string; }> | { emailAddress: MaybePromise<...>; firstName: MaybePromise<...>; id: MaybePromise<...>; lastName: MaybePromise<...>; } | PromiseLike<...>'.
    Type 'User' is not assignable to type '{ emailAddress: MaybePromise<string>; firstName: MaybePromise<string>; id: MaybePromise<string>; lastName: MaybePromise<string>; }'.
      Types of property 'id' are incompatible.
        Type 'ID' is not assignable to type 'MaybePromise<string>'.
          Type 'number' is not assignable to type 'MaybePromise<string>'.

There's https://nexus.js.org/ which is what I started looking at

and then next time i looked at it, it was https://www.nexusjs.org/

they both still exist. seems like lots in flux
@macrozone
Copy link

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
Copy link
Contributor Author

jasonkuhrt commented Jul 21, 2020

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

@macrozone
Copy link

@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
Copy link
Contributor Author

@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
Copy link

@jasonkuhrt this explains a lot, very well done!

I hope we can migrate all our project to framework soon

@janpio janpio unpinned this issue Sep 25, 2020
@jasonkuhrt
Copy link
Contributor Author

For users coming to this now please see the unframework annoucement

@graphql-nexus graphql-nexus locked and limited conversation to collaborators Sep 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type/discussion Discussion about proposals, etc.
Projects
None yet
Development

No branches or pull requests