Giter VIP home page Giter VIP logo

Comments (28)

chrissm79 avatar chrissm79 commented on July 19, 2024 1

Hey @4levels,

From the looks of the error it seems that Lighthouse doesn't know where to look to get the initial set of rooms. You just need to add a @field to the Query type like so:

type Query @group(middleware: ["auth:api", "scopes:graphql"] namespace: "App\\GraphQL\\Queries") {
  rooms: [Room!]! @field(resolver: "Rooms@resolve")
}

The namespace argument isn't required

As for the other questions

  • GraphQL only allows you to create uniquely named types. You could create an interface with the name Comment and name the others RoomComment and BookingComment or just rename the two.
  • You can extend the Query type in different files like so:
# schema.graphql
type Query {
  # ...
}
# rooms.graphql
extend type Query {
  @group(middleware: ["auth:api") {
    rooms: [Room!]!
  }
}
  • The docs are a work in progress but they list many of the directives. The @model is only used if you are using Relay with the Node query, which allows you to resolve any node just by using it's globalId.
  • Nope, they're just regular classes!

Hope that helps!

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Hi @chrissm79,

fantastic response, this should get me going quickly!

Regarding the last question (extend GraphQLResolver or GraphQLQuery): I noticed Lighthouse will look for a query class with the same name as the field in App\GraphQL\Queries (just as I saw this working in @kikoseijo example project) hence my question. From the video tutorial I already learned that this can just be a plain PHP class but I thought to do it "the Lighthouse way" extending these classes instead..

Still working on the Lumen setup part, I'll keep you posted in the PR

Kind regards,

Erik

Update:

  • when I'm not extending the Lighthouse GraphQLResolver or GraphQLQuery class, I can't seem to get the user from the context property. Is the way @kikoseijo does this not recommended then?
    But when I do extend the GraphQLQuery class, I get the following error: Unresolvable dependency resolving [Parameter #0 [ <required> $obj ]] in class Nuwave\\Lighthouse\\Support\\Schema\\GraphQLResolver
  • Regarding the model naming (BookingComment & RoomComment): how can I then tell Lighthouse that the model class for BookingComment is App\Models\Booking\Comment and for RoomComment App\Models\Room\Comment?

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

hi @4levels,

I was playing with v2-beta with no documentation, this is why I have all this mixed up, you know I'm coming from the laravel-graphql like you, and all this not needed now, I should update example.

What make this library so peculiar its that you don't need to define anything apart from the schema to have lots of features implemented. Even more with latest commit!!!

In the config you got your models folder, but you are doing subfolders inside, maybe you should create and extend a model named PostComments to extend from Room\Comment class.

BTW: good tip its that you can resolve where you want, you can call a repository, basically you can reuse code on existing projects, and this is another super cool feature.

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

Forgot to say @4levels, for the context to work you need to make use of the right middlewares. otherwise the auth()->user will never resolve.

I got it like this:

'route' => [
        'prefix' => 'kapi',
        'middleware' => ['web','api', 'loghttp', 'nodebugbar'],    // [ 'loghttp']
    ],
    /*
    |--------------------------------------------------------------------------
    | Namespace registry
    |--------------------------------------------------------------------------
    |
    | This package provides a set of commands to make it easy for you to
    | create new parts in your GraphQL schema. Change these values to
    | match the namespaces you'd like each piece to be created in.
    |
    */
    'namespaces' => [
        'models' => 'App\Models',
        'mutations' => 'App\GraphQL\Mutations',
        'queries' => 'App\GraphQL\Queries',
        'types' => 'App\GraphQL\Types',
        'fields' => 'App\GraphQL\Fields',
        'scalars' => 'App\GraphQL\Scalars',
        'connections' => 'App\GraphQL\Connections',
        'dataloaders' => 'App\\GraphQL\\DataLoaders',
    ],

NOTE: use master branch! πŸ€ͺ

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Hi @kikoseijo @chrissm79,

I couldn't help to notice that there are maybe some issues with the default configuration: when I copied the config.php file to my local projects config/lighthouse.php, I noticed the namespaces are defined using single quotes but with double backslashes. @kikoseijo in your latest message you're even using both single and double backslashes inside single quoted strings. I thought double backslashes are only needed when using double quoted strings.. changing this however doesn't change anything in my project though, I'm still stuck with the following error:

"errors": [
    {
      "message": "Unresolvable dependency resolving [Parameter #0 [ <required> $obj ]] in class Nuwave\\Lighthouse\\Support\\Schema\\GraphQLResolver",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ]

I did add the required middleware's in config/lighthouse.php, like so:

    'route' => [
        'prefix' => '',
        'middleware' => ['auth:api', 'scopes:graphql'],    // [ 'loghttp']
    ],

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

@kikoseijo I also noticed that to have the context with authenticated user working, I have to remove the @auth statement in the graphql schema.
This works:

type Query {
  viewer: User
}

But this doesn't

type Query {
  viewer: User @auth
}

Is this something Lumen related, since I can clearly see from the info @chrissm79 provided that the @auth directive should do the trick..

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

I'm getting more and more confused now, I guess I'll have to wait for the docs ;-)
When I try the @auth directive, I keep getting the following error:

Call to undefined function Nuwave\\Lighthouse\\Schema\\Directives\\Fields\\auth()

When I remove the @auth directive, I can only get context (with the authenticated user in it) when I'm extending the GraphQLQuery (or GraphQLResolver) class, but then I'm running into the forementioned error as soon as I try to get a relation...

Hope to find a solution soon..

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

@4levels the auth its called as a Facade, this is why the auth its not working,
Right now you canΒ΄t use the @auth directive with lumen if you don't activate the facade, its the way was build the directive, I tried to update to remove facade use but was out of my capability scope right now, haven't touched Laravel guards yet.

You can build your own one, I mean, you can build your own directives, here its an example:

<?php

namespace App\GraphQL\Directives;

use GraphQL\Type\Definition\ResolveInfo;
use Nuwave\Lighthouse\Schema\Values\FieldValue;
use Nuwave\Lighthouse\Support\Contracts\FieldResolver;
use Nuwave\Lighthouse\Support\Traits\HandlesDirectives;

class Guard implements FieldResolver
{
    use HandlesDirectives;

    /**
     * Name of the directive.
     *
     * @return string
     */
    public function name()
    {
        return 'guard';
    }

    /**
     * Resolve the field directive.
     *
     * @param FieldValue $value
     *
     * @return FieldValue
     */
    public function resolveField(FieldValue $value)
    {
        return Auth::user();
    }
}

I guess this works, no need to make any more resolvers, the directive will do the job for you.
(At the end of the day, you can have your own query resolver and pull user directly from there)
Context its only something done for you automatically on the way of $context = Auth::user()
And the @auth directive comes with the Laravel Guard.

type Query {
  me: User @guard
}

Maybe @chrissm79 can tell us if it was it posible to use a directive inside an @inject directive?
UPDATE:: I think this is the response:

type Query {
            users(id: ID @neq): [User!]! @paginate(model: "Tests\\\Utils\\\Models\\\User")
        }';

Also, remember you also able to put more middlewares in the request with the @group directive.

type Mutation @group(middleware: ["api:auth"]) {
  createPost(title: String!): Post
}

Ill never be tired of saying this:

Its so simple the way this library been build that you can do same thing on so many different ways thats amazing.

Don't worry to ask, don't wait for documentation, build an example project and ill help you to implement there what you stuck at, its a pleasure. And you are nice an polite, πŸ˜‡

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

The directive does the same than a query, (I like more viewer than me)

<?php

namespace App\GraphQL\Queries;

use Nuwave\Lighthouse\Support\Schema\GraphQLResolver;


class Viewer extends GraphQLResolver
{
    use \App\ResolveLogTrait;

    public function resolve()
    {
        logi(auth()->id());
        // logi(request()->headers->all());
        // $this->resolveLog();
        return $this->context->user;
    }
}

Something silly when I was playing around:

<?php namespace App;

/**
* Trait ResolveLogTrait.
*/
trait ResolveLogTrait
{
    protected function log()
    {
        dbDump();
        logi('');
        // logi($this->obj);
        // dd($this->info);
        logi('OBJ____::: ' . json_encode($this->obj));
        logi('ARGS___::: ' . json_encode($this->args));
        logi('CONTEXT::: ' . json_encode($this->context));
        logi('C-USER_::: ' . json_encode($this->context->user));
        logi('HEADERS::: ' . json_encode($this->context->request->headers));
        logi('INFO___::: ' . json_encode($this->info));
        logi('HEADERS___' . json_encode(request()->headers->all()));
    }
}

I use the use Nuwave\Lighthouse\Support\Schema\GraphQLResolver; because this way I can access all info directly from the $this->XXX,

There are also some helper functions to log all function arguments when you don't know what you getting, was to do with the args_...

Another tip: in the package all possible methods, directives, etc,, have them tests, and you see how to write the schema,

screen shot 2018-04-16 at 20 22 01

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Hi @kikoseijo,

thanks a million for the extensive explanation and encouraging words!
I'll be testing if the Facade calls are the ones to blame here and see if I can work around them.
I'm already using my own fork since I went ahead and replace the obvious facade calls already.

Keep you all posted!
@chrissm79 very right to add the label "Lumen"!

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Hi @kikoseijo

Just to get back on this:

  • re-enabling Facades doesn't seem to make a difference: I keep getting the error Call to undefined function Nuwave\\Lighthouse\\Schema\\Directives\\Fields\\auth() as soon as I add the @auth directive. The Directive itself seems to exist in Schema\Directives\Fields\AuthDirective but somehow Lumen tries to look for the function auth() instead of using this directive.
  • extending the GraphQLQuery class allows retrieval of the user via the $this->context property as long as I don't specify the @auth directive (as seen in your example)

But .. if I simply replace the call to auth($guard)->user() in the AuthDirective with app('auth')->guard($guard)->user() it works! I don't need to extend the GraphQLQuery class anymore (I can even remove the Viewer query class alltogether). I'll be updating my fork so this (hopefully last) Facade call troubles are a thing of the past ;-)

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Ok, so now I'm back to where this issue started..
I'm getting the same error Call to undefined function Nuwave\Lighthouse\resolve() as soon as I try to query a relation (without paginator or relay). The same happens as soon as I add the @model directive when defining types. Enabling Facades doesn't seem to make a difference.

@chrissm79 Can you explain a bit more where / how I'm supposed to use the @model directive? Is this also the place to tell Lighthouse what actual Eloquent model you want to use?
I've noticed that when I do add the @model directive, the graphiql interface fails immediately. On the other hand, when I don't add the directive, the error only shows up during an actual query, but only if I query for the relation.

Upon inspecting the error, I've noticed the GraphQL.php file in Lighthouse calls the resolve function on line 243 & 247 and somehow Lumen cannot find this method. I'll keep fiddling around and report back here..

Current schema.graphql:

scalar DateTime @scalar(class: "DateTime")

type User {
  id: ID! @globalId
  name: String
  email: String
  created_at: DateTime
  updated_at: DateTime
}

type Room {
  id: ID! @globalId
  name: String
  available: String
  reference: String
  details: String
  location: String
  comments: [Comment!]! @hasMany
}

type Comment {
  id: ID! @globalId
  reference: String
  title: String
  content: String
  created_at: DateTime
  room: Room! @belongsTo
}

type ResponsesPayload {
  success: Boolean!
  msg: String
  payload: String
}

type Query {
  viewer: User @auth
  rooms: [Room!]! @field(resolver: "App\\GraphQL\\Queries\\PMS@resolve")
}

Thanks again for all your great support!

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

So close, but I'm currently faliing since Lightouse's internals are still quite far from my comprehension :-(

@chrissm79 Can you (try to) explain how the resolve() call in src/GraphQL.php is supposed to work? Even if I enable Facades, this still fails and my IDE (currently WebStorm) is also unable to go to it's source. When comparing my fork to lighthouse, I also don't see any differences that seem to matter...

@kikoseijo Is your example repo still up to date so I could give it a try, starting from there, just to rule out any of my own possible conflicts (different folder structure, app/GraphQL instead of app/Http/GraphQL etc)?

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

hey @4levels ,
The repo its still on v2-beta, ill update latter and make sure its updated.

Namespaces are not important, i mean, folder structure and namespace dont need to match, its up to you namespaces... you should not go crazy about this.

I think you are not providing the resolve function the params or you mixing the order....

I guess you nearly there,,, you are just about to break the learning curve,.. !!!!

Ill try your changes,, latter on.

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Hi all,

And another update ;-)

I did get around the forementioned error message by replacing the @hasMany directive with @paginate. However, this makes the resulting comments list unaware of the relation with the Room model and returns all comments for each room - I guess this comes from the missing @hasMany directive so the resolver simply paginates over all comments, regardless of the current room.
When I add the resolver property to the @hasMany directive, this doesn't seem to work (makes sense if the type is "relay" / pbbly the hasMany directive doesn't even support the resolver option).

I tried the original master branch with Facades enabled numerous times now (I keep switching back and forth between my own fork with the Facade related changes as soon as I change the schema.graphql) but so far, still no luck: I do get the rooms (as a relay paginator) but the related comments remain empty and the error message is still there: Call to undefined function Nuwave\\Lighthouse\\resolve()

As a side note: as soon as I add the @model directive to any model in the schema, the same error message is thrown even before the GraphiQL interface can load..

Regarding the duplicate model names (with different namespaces): I currently renamed them to be unique as well, but this doesn't seem to make a difference.

@kikoseijo I'm not sure how I can define the resolver in the hasMany directive when using a relay type
@chrissm79 I'm still not 100% sure how to correctly define the directives: I've seen notations where the keys are separated by comma, but in other places I find examples where the comma's are not being used. So should I use eg

comments: [RoomComment!]! @hasMany(type: "relay", relation: "comments")

-- OR -- (without comma's)

comments: [RoomComment!]! @hasMany(type: "relay" relation: "comments")

These is the current schema I'm going with:

scalar DateTime @scalar(class: "DateTime")

type User {
  id: ID! @globalId
  name: String
  email: String
  created_at: DateTime
  updated_at: DateTime
}

type Room {
  id: ID! @globalId
  name: String
  available: String
  reference: String
  details: String
  location: String
  comments: [RoomComment!]! @hasMany(type: "relay", relation: "comments")
}

type RoomComment {
  id: ID! @globalId
  reference: String
  title: String
  content: String
  created_at: DateTime
  room: Room! @belongsTo
}

type ResponsesPayload {
  success: Boolean!
  msg: String
  payload: String
}

type Query {
  viewer: User @auth
  rooms: [Room!]! @paginate(type: "relay", model: "App\\Models\\Room\\Room")
}

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

Mr @4levels,

If you could just upload your project, or the main parts... you know, some migrations and seeders, and ill work it out today.

No need full project, just the parts you working on right now, im sure we will go faster from there.

Here its an example:
https://github.com/chrissm79/lighthouse-belongs-to-many

Here its another:
https://github.com/nuwave/lighthouse-todo-example

and another:
https://github.com/nuwave/lighthouse-example

Just in case any of this examples has similar code, or we can provide more code to this for others to see working examples.

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Hi @kikoseijo and @chrissm79

I'm just from creating the repo, you can find it here: https://github.com/4levels/lighthouse-relay

Hope this can shed some light.. currently it's using Facades and I'm not using my forked version of Lighthouse..

Thanks again!

You'll need to replace the calls to file_get_contents('/run/keys/xxx') with some passwords and for the oauth seeder to work, you'll need to create a php file config/secrets.php containing some clients, users and scopes, eg:

<?php

return [
    "clients" => [
        "default" => [
            "id" => "1",
            "secret" => file_get_contents('/run/keys/local.api.clients.default.secret'),
            "scopes" => "login graphql",
            "name" => "Default client",
            "location" => "1,2"
        ],
    ],
    "users" => [
        "[email protected]" => [
            "id" => "1",
            "name" => "Test user",
            "password" => file_get_contents('/run/keys/[email protected]'),
            "client_id" => "default"
        ],
    ],
    "scopes" => [
        "login" => "Login scope",
        "graphql" => "Access to the GraphQL endpoints"
    ]
];

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

@kikoseijo
One remark about the links you provided with example projects: none of them has a schema.graphql file, @chrissm79 are they not included because of .gitignore entries?

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

@4levels them on routes

https://github.com/chrissm79/lighthouse-belongs-to-many/blob/master/routes/graphql/schema.graphql

https://github.com/nuwave/lighthouse-todo-example/blob/master/routes/schema.graphql

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Hi @chrissm79,

I'm currently looking with @kikoseijo why this error is so persistent (call to undefined method resolve() )
Can you please provide some more info regarding my questions about the resolve function? How is this supposed to work, seeing that there's no resolve function, yet it's being called directly?

Thanks in advance!

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

Allright,

I think I found the error but not been able to find why, maybe @chrissm79 can give me a tip,

type User @model {

I can't use the @model directive in order to embed the model inside de Node.

This is when we get this error.

Call to undefined function Nuwave\Lighthouse\resolve()

1st image its without the directive and second with it.

screen shot 2018-04-18 at 17 07 39

screen shot 2018-04-18 at 17 07 49




I can confirm its related to LUMEN.



from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

Got error traced to here:

    /**
     * Instance of Node container.
     *
     * @return NodeContainer
     */
    public function nodes()
    {
        if (! app()->has(NodeContainer::class)) {
            return app()->instance(
                NodeContainer::class,
                resolve(NodeContainer::class)
            );
        }

        return resolve(NodeContainer::class);
    }

There are so many resolve functions declared.....

from lighthouse.

chrissm79 avatar chrissm79 commented on July 19, 2024

@kikoseijo Thanks for all of your help on this! Been pretty backed up but I'll try to provide some feedback during lunch.

Is the resolve helper method included w/ Lumen?

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

Allright!

there you are:, no we got no helpers in Lumen.
like the app_path

from lighthouse.

kikoseijo avatar kikoseijo commented on July 19, 2024

Working now @4levels , simple helper method did the job, its pending publishing.

To close this @chrissm79 , whats the job of the @model, I can't figure out if its of any use, can you provide some info?

screen shot 2018-04-18 at 20 07 50

query RoomsQuery{
  rooms(first:10){
    pageInfo{
      hasNextPage
    }
    edges{
      node{
        id
        name
        comments(first:10){
          edges{
            node{
              id
              title
            }
          }
        }
      }
    }
  }
}

from lighthouse.

chrissm79 avatar chrissm79 commented on July 19, 2024

@kikoseijo Thanks for your help with this!! So the @model directive just registers a Node which is used by Relay (you can use it with something like apollo also, but I'm not sure if it provides the same benefits as Relay).

The Node interface basically allows Relay (and any other GraphQL client) to query for a type based on it's global id.

So let's use your query example from above:

query RoomsQuery{
  rooms(first:10){
    pageInfo{
      hasNextPage
    }
    edges{
      node{
        id
        name
        comments(first:10){
          edges{
            node{
              id
              title
            }
          }
        }
      }
    }
  }
}

And let's pretend that a Comment had an upvote field. The current query doesn't ask for the upvotes field, but let's say the user clicked the comment and now we need to show the total upvotes with the following query:

query Comment {
  comment(id: "some-global-id") {
    id
    title
    upvotes
  }
}

Relay knows that we already have the id and the title and the only other field we need is the upvotes so it can choose to send the following request instead:

query Node {
  node(id: "some-global-id") {
    ... on Comment {
      upvotes
    }
  }
}

Hopefully that made sense πŸ˜„, but personally I use Apollo and while I still use global id's (makes updating the cache pretty easy) I don't use the @model or @node directives in my projects.

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

Hi @kikoseijo & @chrissm79,

it started indeed working as soon as I added the helper function resolve (copied it from the Laravel framework repo), such a minor thing to resolve this major issue! I guess I was looking too closely (I should have known, from all these questions regarding the resolve function).

Very glad it's fixed!

@chrissm79 I'm not fully understanding what this resolve function actually does, as it seems to be nothing more than an alias for the app() function. If that's the case, why not simply use app() instead of resolve() then? One less helper needed imho.

Now I'm back to trying this to run without Facades alltogether, using my fork so I can finalize the PR

Keep you posted here!

Kind regards and thanks again for all the help!

from lighthouse.

4levels avatar 4levels commented on July 19, 2024

@chrissm79 One final question (I hope):
Would it be feasable to be able to specify in the @model directive which model class is supposed to be used?
I think this would be the easiest way to tell the GraphQL in the schema how a GraphQL model is supposed to translate to the Eloquent model, as an alternative to use strictly unique class names instead..

from lighthouse.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.