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 Next 13 app directory and Keystone getContext #8371

Merged
merged 13 commits into from
Apr 13, 2023

Conversation

borisno2
Copy link
Member

@borisno2 borisno2 commented Mar 5, 2023

Adding Keystone in the Nextjs app directory example showing how to use getContext within Server Rendered Components. This example uses the document renderer, the scope of the example is not to show how authentication or session management should work - the suggestion at this stage is to use context.withSession

@changeset-bot

This comment was marked as resolved.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Mar 5, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 91e011e:

Sandbox Source
@keystone-6/sandbox Configuration

@borisno2 borisno2 self-assigned this Mar 5, 2023
@gautamsi
Copy link
Member

gautamsi commented Mar 6, 2023

@borisno2 Thanks for this, I was struggling with this when I tried your work in "On The Hill Drama" in my repo.

For auth I think having default keystone based login in admin-ui should be possible with some changes.

@borisno2
Copy link
Member Author

borisno2 commented Mar 6, 2023

@borisno2 Thanks for this, I was struggling with this when I tried your work in "On The Hill Drama" in my repo.

For auth I think having default keystone based login in admin-ui should be possible with some changes.

No worries @gautamsi I am hoping to create some more videos over the coming weeks covering how I did auth (using next-auth) and vercel deployment, let me know if you think there would be other things that would be valuable to cover

@dcousens dcousens changed the title [WIP] - Keystone in Next App Dir [WIP] - Add example for Next 13 and getContext Mar 7, 2023
@gautamsi
Copy link
Member

gautamsi commented Mar 7, 2023

It would be valuable to use in built authentication instead of next-auth to start with, next-auth is add-on and even better way to do things but in-built stuffs should work.

@jlarmstrongiv
Copy link

I am hoping to create some more videos over the coming weeks covering how I did auth (using next-auth)

@borisno2 that would be very helpful! Looking forward to it 😄

@gautamsi
Copy link
Member

any update on this?

@borisno2 borisno2 force-pushed the keystone-in-next-app-dir branch from 99f0e8a to 26db5cc Compare March 20, 2023 04:22
@gautamsi
Copy link
Member

if I add 'use client'; to

  1. packages/fields-document/src/DocumentEditor/utils.ts
  2. packages/fields-document/src/validation.ts

this allows me to run the PR with document field

@dcousens dcousens changed the title [WIP] - Add example for Next 13 and getContext [WIP] - Add example for Next 13 app directory and Keystone getContext Mar 22, 2023
@borisno2 borisno2 force-pushed the keystone-in-next-app-dir branch 3 times, most recently from c7e69fd to 99d7c34 Compare March 29, 2023 02:39
@borisno2 borisno2 force-pushed the keystone-in-next-app-dir branch from 8c3da68 to d11b350 Compare March 29, 2023 21:30
@borisno2 borisno2 marked this pull request as ready for review April 5, 2023 02:00
@borisno2 borisno2 changed the title [WIP] - Add example for Next 13 app directory and Keystone getContext Add example for Next 13 app directory and Keystone getContext Apr 5, 2023
@borisno2 borisno2 requested a review from dcousens April 11, 2023 01:30
@dcousens dcousens force-pushed the keystone-in-next-app-dir branch 3 times, most recently from d252ad8 to 81ed2fb Compare April 11, 2023 02:51
@dcousens dcousens force-pushed the keystone-in-next-app-dir branch from 2fa21c2 to a666fe6 Compare April 12, 2023 07:13
@dcousens dcousens force-pushed the keystone-in-next-app-dir branch from 62af1a9 to b831ed8 Compare April 13, 2023 01:20
@dcousens dcousens merged commit 0f99cf1 into main Apr 13, 2023
@dcousens dcousens deleted the keystone-in-next-app-dir branch April 13, 2023 02:10
@jlarmstrongiv
Copy link

It’s looking good 😄

The NextJS Beta docs are encouraging the Route Handlers, which have replaced the API Routes

I’d like to see an example of the getServerSession

It may be good to reference the @prisma/nextjs-monorepo-workaround-plugin

Ahh, serverComponentsExternalPackages: ['graphql'], thanks for including that

So glad to see this example 🎉

@dcousens
Copy link
Member

dcousens commented Apr 13, 2023

I’d like to see an example of the getServerSession

Authentication is hard.

I think it is easier for us to have authentication in a few examples, maintain them really well, and then keep the rest of the examples authentication free.
The const session = {} with a disclaimer hopefully showcases the boilerplate you'll find yourself writing, without importing too many opinions about what kind of authentication you might use.
We don't want to extend the examples beyond their scope of integrating with @keystone-6/*.

Interested to hear if you think otherwise 💛

@borisno2
Copy link
Member Author

It’s looking good 😄

Thanks!

The NextJS Beta docs are encouraging the Route Handlers, which have replaced the API Routes

Agreed, although route handlers also need to be supported by the GraphQL server - in this case graphql-yoga - this is something I haven't really tested as yet, as their docs don't yet speak to this implementation. The NextJS beta docs also mention that Route Handlers are not necessarily the answer to data mutation - while this area is still very much shifting I didn't want to commit to a method that will most likely change soon.

I’d like to see an example of the getServerSession

I have just recorded a video of how I am doing this in my project. Would love some feedback, as @dcousens mentioned it is hard to make a generic example as Authentication is hard and often very project specific, or any example would just go into how to use next-auth or some other provider.

It may be good to reference the @prisma/nextjs-monorepo-workaround-plugin

Good callout, I haven't run into that issue, but maybe that is due to our use of a custom Prisma Client location. How do you think this is best to be called out?

Ahh, serverComponentsExternalPackages: ['graphql'], thanks for including that

So glad to see this example 🎉

Glad it is helpful!

@jlarmstrongiv
Copy link

jlarmstrongiv commented Apr 19, 2023

Authentication is hard.

Definitely. I always try to lean on a framework or library to support it. Authentication is hard to get right.

I think it is easier for us to have authentication in a few examples, maintain them really well, and then keep the rest of the examples authentication free.

Sure! I noticed you’re working on a supabase example in https://github.com/keystonejs/keystone/pull/8469/files There was only one auth example, so that’s why I’m interested in more details.

We don't want to extend the examples beyond their scope of integrating with @keystone-6/*.

I think that social auth is important though. Examples with some of these libraries would be very helpful:

With getContext and other use cases like integrating with mobile apps or multiple servers, there needs to be a way to authenticate without cookies too.

Agreed, although route handlers also need to be supported by the GraphQL server - in this case graphql-yoga - this is something I haven't really tested as yet, as their docs don't yet speak to this implementation. The NextJS beta docs also mention that Route Handlers are not necessarily the answer to data mutation - while this area is still very much shifting I didn't want to commit to a method that will most likely change soon.

I think a workaround may be including the yoga server in both the GET and POST routes, but I can see waiting until the app dir is more stable. Actually, would that fail due to the cookies requiring the same server?

Good callout, I haven't run into that issue, but maybe that is due to our use of a custom Prisma Client location. How do you think this is best to be called out?

I think both that and serverComponentsExternalPackages: ['graphql'], can be called out in the README for that example.

KeystoneJS has done very well with access control. I like how it manages access to both the API and UI, with support for roles and granular permissions. It’s really well done.

It’s the authentication pieces that are still complex, especially since a lot of functionality and examples are not built into core.

I have just recorded a video of how I am doing this in my project. Would love some feedback, as @dcousens mentioned it is hard to make a generic example as Authentication is hard and often very project specific, or any example would just go into how to use next-auth or some other provider.

Awesome! I’ll check that out later tonight. Thank you

@mmachatschek
Copy link
Contributor

@borisno2 coming back to this discussion.

Agreed, although route handlers also need to be supported by the GraphQL server - in this case graphql-yoga - this is something I haven't really tested as yet, as their docs don't yet speak to this implementation. The NextJS beta docs also mention that Route Handlers are not necessarily the answer to data mutation - while this area is still very much shifting I didn't want to commit to a method that will most likely change soon.

graphql-yoga added the next.js app router examples to their docs here dotansimha/graphql-yoga#2760

basic example:

import { createSchema, createYoga } from 'graphql-yoga'
 
const { handleRequest } = createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        greetings: String
      }
    `,
    resolvers: {
      Query: {
        greetings: () => 'This is the `greetings` field of the root `Query` type'
      }
    }
  }),
 
  // While using Next.js file convention for routing, we need to configure Yoga to use the correct endpoint
  graphqlEndpoint: '/api/graphql',
 
  // Yoga needs to know how to create a valid Next response
  fetchAPI: { Response }
})
 
export { handleRequest as GET, handleRequest as POST }

unfortunately with the app router its not possible to do keystoneContext().withRequest(req, res) because the withRequest() function expects IncomingMessage and OutgoingMessage as params, which are not provided by the app router anymore as they use the web standard (Request, Response) objects.

@borisno2
Copy link
Member Author

borisno2 commented Sep 26, 2023

Hey @mmachatschek
Thanks for bringing this up. I have been using GraphQL API in the route handler for some time now - although using Apollo not Yoga - and it is working well. You are correct though, you would need to use context.withSession and use NextJS to construct your session. I'll update the example to use the route handler soon.
Thanks

@dcousens
Copy link
Member

dcousens commented Sep 26, 2023

context.withRequest is honestly only a wrapper of sessionStrategy.get + context.withSession.

We loving hearing feedback like this @mmachatschek as it helps us understand what abstractions might better serve us in respect to things like our getSession experiment et cetera

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

Successfully merging this pull request may close these issues.

5 participants