Nested namespace for better structure of GraphQL classes - PHP lighthouse

Current config options don't allow to group together same type of query in App/GraphQL directory

currently namespace key in lighthouse config file has following

   'namespaces' => [
        'models' => 'App\\GraphQL\\Models',
        'queries' => 'App\\GraphQL\\Queries',
        'mutations' => 'App\\GraphQL\\Mutations',
        'subscriptions' => 'App\\GraphQL\\Subscriptions',
    ],

solution that exist I know we can use arrays to solve , but if i have 10 sub folders .... adding all of them would be not so good if it goes up to 20 or 30... like it beats the purpose of simplicity and non tediousness kinda?

we are supposed to have all of our files in one folder. But it would be great if we can group together in folders. say like all Mutation concerned with Authentication Logic can go in its own folder.

Which possible solutions should be considered? may be we can use wildcard like in schema files we use to import nested schema. ? or just simply all allow files inside some schema?

Thanks.

Asked Sep 21 '22 11:09
avatar pankajvaghela
pankajvaghela

11 Answer:

You can customize the folders in the config file, something like the follow it helps you to add even following some regex or sub folders:

'namespaces' => [
        'models' => str_replace([base_path().DIRECTORY_SEPARATOR, "/"], ["", "\\"], glob(base_path('Modules/**/Models'), GLOB_ONLYDIR)),
        'queries' => str_replace([base_path().DIRECTORY_SEPARATOR, "/"], ["", "\\"], glob(base_path('Modules/**/GraphQL/Queries'), GLOB_ONLYDIR)),
1
Answered Oct 08 '20 at 23:48
avatar  of faiverson
faiverson

@pankajvaghela thanks for the issue and @faiverson thanks for the suggestion.

Using nested namespaces for GraphQL classes is discouraged, because the GraphQL schema itself has no namespaces. By keeping all your classes within a flat list, name collisions are naturally impossible.

1
Answered Oct 09 '20 at 10:17
avatar  of spawnia
spawnia

okay so i tried @faiverson 's solution...

I have folder structure similar to this

  | - Models 
  | - | - Blog
  | - | - | - BlogPost
  | - | - | - BlogComment
  | - | - User

I tried following ...

models => str_replace([base_path().DIRECTORY_SEPARATOR, "/"], ["", "\\"],  glob(base_path('App/Models/**'), GLOB_ONLYDIR));

i tried following paths too

'App/Models/**'
'App/Models/**/**'

but it results in error finding user model

"message": "No class 'User' was found for directive 'paginate'",

1
Answered Oct 09 '20 at 15:02
avatar  of pankajvaghela
pankajvaghela

@faiverson @spawnia can we please look more into this?

I know sometimes we are busy with stuff and it takes time for reply but otherwise atleast keep it open? thanks

1
Answered Oct 11 '20 at 14:21
avatar  of pankajvaghela
pankajvaghela

Using nested namespaces for GraphQL classes is discouraged, because the GraphQL schema itself has no namespaces. By keeping all your classes within a flat list, name collisions are naturally impossible.

@faiverson I agree but then its be long list of classes or in one folder and it gets unmanageable after one point or is not very good to work with.

I am trying to organize normal models as per where they belong... so name collission could be problematic but it would be worth taking care of if i dont have to write every folder name in config file

1
Answered Oct 11 '20 at 14:25
avatar  of pankajvaghela
pankajvaghela

I consider namespaces harmful as they do not align with the feature set that GraphQL provides. Any step towards making them easier to use is actively working to promote such problematic use.

1
Answered Oct 12 '20 at 15:29
avatar  of spawnia
spawnia

Try to check the file vendor/nuwave/lighthouse/src/Schema/Directives/BaseDirective.php function namespaceClassName and function namespaceModelClass in order to get more info about what is the namespace your User model is resolving or why it is not working for you. Those function are in charge of resolve the model namespaces. In my project I have models in folders like `Modules\MyModule\Entities\Model.php and it is working perfectly fine.

1
Answered Oct 12 '20 at 16:52
avatar  of faiverson
faiverson

if anyone finds needs this in future I used this little helper function for my use case ```(php) function getNestedNameSpaces(string $type, $level = 0) { $curBasePath = "app/$type"; $dirs = [];

  while ($level >= 0) {
     $newDirs = str_replace(
        ["app\\"],
        ["App\\"],
        str_replace(
           [base_path().DIRECTORY_SEPARATOR, "/"],
           ["", "\\"],
           glob(base_path($curBasePath), GLOB_ONLYDIR)
        )
     );
     $dirs = array_merge($dirs, $newDirs);
     $curBasePath = "$curBasePath/**";
     $level--;
  }
  return $dirs;

}


 'namespaces' => [
     'models'        => getNestedNameSpaces('Models', 2),
     'queries'       => getNestedNameSpaces('GraphQL/Queries', 2),
     'mutations'     => getNestedNameSpaces('GraphQL/Mutations', 2),
     ...
]
Why @faiverson's following approach didn't work for me

strreplace([basepath().DIRECTORYSEPARATOR, "/"], ["", "\"], glob(basepath('Modules/**/GraphQL/Queries'), GLOB_ONLYDIR))

- it was for **Modules** directory in root,  while laravel uses **app** directory.
- it assumes every **module has graphql/Queries** folder... i needed **modules in query folder.**

It didnt work when I used `'App/Queries/**'` either 
- laravel uses **app** folder with lowercase A. 

So I uses app with lowercase A in the above statement and that results in

"Queries" => [ "appGraphQLQueries", ], ```

then i got namespace error, no Resolver found in namespace because of that small a in app, namespaces uses App while directory is app.

So I had to replace that app with App and it worked

1
Answered Mar 24 '21 at 07:39
avatar  of pankajvaghela
pankajvaghela

I have made it clear multiple times that namespaces are harmful, so I am locking this conversation.

1
Answered Mar 24 '21 at 08:02
avatar  of spawnia
spawnia


We offer our clients with the best-in-class services which becomes the ultimate one stop solution for all their Global investment needs.

https://orientfinance.com/

1
Answered Sep 21 '22 at 11:09
avatar  of James Robert
James Robert

Scorpion Property is a real estate company, which is located at the heart of Dubai “JBR Walk”. We deal in buying, selling, renting and managing properties all over Dubai.



1
Answered Sep 21 '22 at 11:09
avatar  of John Michael
John Michael