nuwave / lighthouse

A framework for serving GraphQL from Laravel
https://lighthouse-php.com
MIT License
3.33k stars 433 forks source link

Create a real world tutorial to help everybody understand Laravel Lighthouse step by step #1476

Closed wolfiton closed 3 years ago

wolfiton commented 4 years ago

I am willing to provide most of the code to create a functional blog with auth using vue-apollo What problem does this feature proposal attempt to solve? This solves the getting started and the tutorial section of the docs with a real-world example, That will make more people or companies adopt Laravel Lighthouse into their projects.

The docs and tutorials are not very detailed on how to solve certain important features that you will find in a real-world app. Which possible solutions should be considered? Creating a real-world blog to show the value of Laravel Lighthouse

I don't know any other solutions to this problem.

Thanks for looking over my proposal.

lorado commented 4 years ago

Same as for upload example - go ahead and create it in extra repo. You could actually use the repo you already created for upload, and extend it. We could somewhere link your project in docs.

There is one thing makes me warily - as lighthouse grow and probably change some APIs, or introduce some new stuff, that breaks old stuff, you have to update your example. Do you think you can keep your example up to date?

spawnia commented 4 years ago

Have you looked at https://github.com/nuwave/lighthouse-example yet? It is a quite minimal example I created according to best practices I found.

It can be more complete for sure. A comprehensive overview would help greatly, too. I put a great focus on implementing proper tests for it to ensure that the example code actually works.

wolfiton commented 4 years ago

Same as for upload example - go ahead and create it in extra repo. You could actually use the repo you already created for upload, and extend it. We could somewhere link your project in docs.

There is one thing makes me warily - as lighthouse grow and probably change some APIs, or introduce some new stuff, that breaks old stuff, you have to update your example. Do you think you can keep your example up to date?

I will keep it up to date because I want to learn it so I can use it in production in my own apps. If you guys continue to offer support than we can definitely make something great.

I think in this way we all win:

Thanks for the quick feedback on this.

genesiscz commented 4 years ago

Have you looked at https://github.com/nuwave/lighthouse-example yet? It is a quite minimal example I created according to best practices I found.

It can be more complete for sure. A comprehensive overview would help greatly, too. I put a great focus on implementing proper tests for it to ensure that the example code actually works.

There are a lot of things not used/answered, such as whole app/GraphQL directory possibilities. First thing that comes to my mind is, add an updatePost so only you, as a logged in user, can update the post.

spawnia commented 4 years ago

@genesiscz open for PR's that add bits of functionality to the example project!

genesiscz commented 4 years ago

@genesiscz open for PR's that add bits of functionality to the example project!

I'd love to contribute, trust me, but my comment was more from the observer & someone who request this from somebody who knows the correct way to do something. I am using types, Queries, Mutation classes, but I am not sure I use them correctly or what are the possibilities. For example, I am not sure how is the BatchLoader used (I know there's a resource for that, but we're talking about the example here)

wolfiton commented 4 years ago

Does someone have any pointers on how to add sanctum to this current example? It uses vue fro frontend and Lighthouse for backend this also closes the example on how to upload using lighthouse.

https://github.com/wolfiton/vue-upload

spawnia commented 4 years ago

https://github.com/nuwave/lighthouse-example/pull/9

wolfiton commented 4 years ago

nuwave/lighthouse-example#9

Do I have any context where I can store the toekn and the headers in lighthouse?

wolfiton commented 4 years ago

I already saw this part under security and the example you provided but my problem is how to store everything in the context so i can access them using vue.

Also please take a look at helmet from nodejs to see an example why I am asking for headers.

The link to helmet

spawnia commented 4 years ago

You can use plain old middleware to add HTTP headers.

wolfiton commented 4 years ago

You can use plain old middleware to add HTTP headers.

That is very good, thanks @spawnia,

Now for the tricky part once I create a login mutation, I need to verify that the user has the corresponding role and generate a token ability based on that check, also when the app goes offline or enters PWA mode. I need to revoke any tokens with:

Create a custom arg resolver for the mutattion somehoiw bring the middleware and generate token based on roles

Bad idea: To store the role with the token.

Thanks for any insight into this.

spawnia commented 4 years ago

I think you might be conflating concepts here. It is my understanding that the roles in a token are supposed to be relatively static and reflect what the user is authorized to do. Generating that once on Login seems sufficient?

wolfiton commented 4 years ago

I think that i would like to hear more opinions on this security matter because a cookie that is not http can be tempered easily and create havoc in an application. You can follow further here https://stackoverflow.com/questions/62951098/laravel-lighthouse-sanctum-role-based-tokens-best-pratices-and-security

Using sanctum is not secure and has some restriction if you need an SSR or something else like a jwt token. So in my opinion if you can help me implement a passeto guard for auth that would be good. If not i don't want to create something that is insecure and pretend that it is.

Why not sanctum?

The tokens are stored in db using sha256 BAD! The tokens can be read as plaintext BAD! The tokens are not encrypted using private key and public key BAD!

Why passeto?

Read this blog post from a security expert that does this everyday https://developer.okta.com/blog/2019/10/17/a-thorough-introduction-to-paseto

wolfiton commented 3 years ago

Are we going to implement a passeto auth?

Will I get support if I start the login feature using paseto on the project or this is not an option?

Thanks in advance for the response

spawnia commented 3 years ago

Paseto seems great. I would be interested in how it can be implemented, since we are currently considering if we should use JWT, Passport, Sanctum, Paseto... in our application.

lorado commented 3 years ago

I would also like to see how paseto can be used. I only heard about it last month, but didn't use it in my apps. I was actually thinking to try out paseto. @wolfiton as you already found a lumen example, it should be quite simple to use it in laravel, I think it works exactly the same. So, try it out ;)

genesiscz commented 3 years ago

nuwave/lighthouse-example#9

I know this is a little bit off topic, but did you ever had a problem with using cookies that are not stored in the same domain in safari?

I am trying to use session because I am working on a Cart in database which is using session_id to "remember" the person and it works if I use "api" middleware in lighthouse configuration which is slightly edited to include the session cookies in that middleware:

           \Illuminate\Session\Middleware\StartSession::class,
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,

            EnsureFrontendRequestsAreStateful::class,

It works in Chrome but does not on Safari. I know it's because of the third party cookie "do not track" option Safari has, but is a problem I found no elegant solution to anywhere. I am getting the Cart record from the db through a Lighthouse Query which first searches for a cart that has the session ID and creates a new one if not created.

My thought on this was that I can use a token approach but it would require to create a token for every guest on the page which I don't know if I like.

wolfiton commented 3 years ago

I will try and come back on Friday with the login. I have some thing to catch up on my own. Thanks in advance for understanding and the support for this example.

wolfiton commented 3 years ago

Back as i promised. Now I was thinking of creating an overview and also ask your opinions on this example project. My idea is that this blog should have the following so that it could be used as a real wolr example:

Also, I have two frameworks that we can use on the frontend to build this using SSR: quasar and nuxtjs.

What do you guys think about those ideas?

Any additions or opinions are welcomed.

spawnia commented 3 years ago

The feature set seems nice, @wolfiton.

It would be nice to have a Facebook-like kind of dashboard which shows a bunch of data at once, GraphQL can really shine there.

I have no experience with Vue, only used React so far. Looks like Quasar is more opinionated, which might be a good fit for a demo project. The less boilerplate there is, the more the actual application code can shine.

One strong recommendation I have for the frontend is to use TypeScript + https://graphql-code-generator.com/. Having typesafe APIs that are certain to match the schema is such a boost for productivity and correctness.

wolfiton commented 3 years ago

The feature set seems nice, @wolfiton.

It would be nice to have a Facebook-like kind of dashboard which shows a bunch of data at once, GraphQL can really shine there.

I have no experience with Vue, only used React so far. Looks like Quasar is more opinionated, which might be a good fit for a demo project. The less boilerplate there is, the more the actual application code can shine.

One strong recommendation I have for the frontend is to use TypeScript + https://graphql-code-generator.com/. Having typesafe APIs that are certain to match the schema is such a boost for productivity and correctness.

Can a user profile have this effect in our app @spawnia ?

I haven't used typescript outside of some angular apps so I don't have much experience with it in vue or quasar but I will try.

Also, would it be a good idea to create an interface for users and also an enum for roles?

Or what is the best way to organize this features?

Thanks

spawnia commented 3 years ago

Can a user profile have this effect in our app @spawnia ?

It does not necessarily have to be personalized, although parts of it might be. I think it would be cool to have a bunch of different data sources all on the same page.

Also, would it be a good idea to create an interface for users

Might be good if they share a bunch of fields, but differ in others.

an enum for roles?

I tend to use Enums every time a value is actually enumerable, which roles are likely to be. Consider defining them in PHP, since that allows reuse in both the schema and the model: https://lighthouse-php.com/master/the-basics/types.html#native-php-definition

wolfiton commented 3 years ago

Can a user profile have this effect in our app @spawnia ?

It does not necessarily have to be personalized, although parts of it might be. I think it would be cool to have a bunch of different data sources all on the same page.

Also, would it be a good idea to create an interface for users

Might be good if they share a bunch of fields, but differ in others.

an enum for roles?

I tend to use Enums every time a value is actually enumerable, which roles are likely to be. Consider defining them in PHP, since that allows reuse in both the schema and the model: https://lighthouse-php.com/master/the-basics/types.html#native-php-definition

On problem i am facing is that neither vue apollo offer an example of typescript support or quasar apollo https://github.com/quasarframework/app-extension-apollo. So i think that i am asking for trouble trying to use something that is not implemented. I am also willing to continue the integration of typescript but i will need you help to define the types. Just like this example:

export interface Todo {
  id: number;
  content: string;
}

export interface Meta {
  totalCount: number;
}

For apollo apolloClient and the rest of the apollo family methods.

wolfiton commented 3 years ago

Better yet if you guys have more experience with react and can help and contribute more than let's just switch the project to nextjs typescript apollo that has some examples.

What are your opinions on this?

spawnia commented 3 years ago

Manually re-defining the schema types in the frontend is very tedious. Especially when you consider that each and every query chooses just a subset of fields, which requires extra types. GraphQL Codegen takes care of all of that. I guess it will not work with Quasar, but plain vue-apollo should be fine: https://graphql-code-generator.com/docs/plugins/typescript-vue-apollo

I found Next.js quite nice to work with, personally and know the TypeScript + React + Apollo combination to work quite well.

wolfiton commented 3 years ago

Manually re-defining the schema types in the frontend is very tedious. Especially when you consider that each and every query chooses just a subset of fields, which requires extra types. GraphQL Codegen takes care of all of that. I guess it will not work with Quasar, but plain vue-apollo should be fine: https://graphql-code-generator.com/docs/plugins/typescript-vue-apollo

I found Next.js quite nice to work with, personally and know the TypeScript + React + Apollo combination to work quite well.

Ok then let's switch to something that is more familiar to you guys so I can receive some support if needed and also to make my life easier with graphql code generator.

lorado commented 3 years ago

Here are my opinions:

I never used React, so if we go react way, I will not be able to help you there at all. @spawnia has there more expertise

In my projects I use nuxt.js with TS, and it works pretty well. To be honest - TS support in vue 2 and therefore in nuxt.js is "OK"ish, there are possibilities to work with it. I found a way, and I could provide the boilerplate with apollo and graphql-codegen configured. As Vue 3 is rewritten in TS completely, it provide completely TS support. I guess nuxt.js with vue 3 will be then released within a month after Vue 3 release. As I use this stack in my projects, I could also help to migrate later to nuxt with Vue 3. Vue 3 is gonna to be released in august this year

So it is up to you, what you want to use. In the real world both vue.js and react are awesome frameworks to work with.

wolfiton commented 3 years ago

We can create it using both tehnologies, as I have some experience with react and vue at the same time. In nuxtjs i always had a problem finding a good midleware example that doesn't use express middleware.

So if both of you agree than I can do this example in both frameworks:

Also for the boilerplate so that the example look ok I would suggest we go with material ui for both frameworks.

What do you guys think can we do it in both?

Thanks in advance

spawnia commented 3 years ago

@wolfiton i am pretty busy working on Lighthouse core and some other open source projects, so I probably won't be able to put much time into building your example app anyways. Choose what you are most comfortable with.

One nice thing about GraphQL is that the schema provides a clear contract to build upon, so adding another frontend to consume should be easy.

lorado commented 3 years ago

@wolfiton same here. Busy at main work + working on some side projects. But as I said, I am able to help due giving you directions, where to look at, and giving you some (adopted) examples of code, help you a little.

wolfiton commented 3 years ago

@wolfiton i am pretty busy working on Lighthouse core and some other open source projects, so I probably won't be able to put much time into building your example app anyways. Choose what you are most comfortable with.

One nice thing about GraphQL is that the schema provides a clear contract to build upon, so adding another frontend to consume should be easy.

Ok Thanks for letting me know.

wolfiton commented 3 years ago

@wolfiton same here. Busy at main work + working on some side projects. But as I said, I am able to help due giving you directions, where to look at, and giving you some (adopted) examples of code, help you a little.

Ok, can you send me the setup for nuxt typescript and apollo with codegen. I would be very grateful so i can starte building this example. Thanks @lorado

wolfiton commented 3 years ago

@lorado, I foud this post that shows how to integrate nuxtjs with typescript is your setup similar to this?

https://www.codegram.com/blog/nuxt-typescript-apollo-a-bumpy-road/

Thanks

lorado commented 3 years ago

Didn't see this in detail, kind of... I don't know how is it looking now, but I had to write some additional code, to get it working on server side too. Also I am using multiple apollo-links, and I can add callbacks to upload-progress, very useful if you upload large files. I'll drop my code to your repo till Monday ;)

spawnia commented 3 years ago

Closing this issue, happy to see your result. You can add a PR to link to it in https://github.com/nuwave/lighthouse/blob/master/docs/resources/README.md