graphiti-api / graphiti

Stylish Graph APIs

Home Page:https://www.graphiti.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is it possible to get a list of all Resource class names?

Ben-Fenner opened this issue · comments

I'm trying to write our own API documentation but also automate it as much as possible.
Is there a way to get a list of all Resources sort of like Graphiti::Resource.all?

Then I could loop over them and their attributes to output if they are sortable, filterable, etc.

Is there anything like that? I don't recall coming across it in the documentation (and I've read it so many times).

I guess worst case scenario I can introspect the resources directory... =/

Until I figure out something better, I'm introspecting the resources directory.
Here's that code if anyone else wants to use it:

    resource_location   = '/app/app/resources'
    resource_file_names = Dir.entries(resource_location).select{ |entity| File.file?(File.join(resource_location, entity)) && entity.ends_with?('_resource.rb') }
    resource_classes    = resource_file_names.map{ |file_name| file_name.chomp('.rb').camelize.constantize }
    resource_classes    = resource_classes.reject(&:abstract_class?)

I hope to soon be able to avoid this with something much simpler, but here I am for now.

You could query the schema for that i guess ..

[9] pry(main)> Graphiti::Schema.generate.fetch(:resources).collect { |r| r[:name] }
=> ["BugResource",
 "DepartmentResource",
 "EmployeeResource",
 "EpicResource",
 "FeatureResource",
 "MilestoneResource",
 "NoteResource",
 "PositionResource",
 "TaskResource",
 "TeamResource"]

That's a bit more like what I was looking for. Thank you so much!

Oh boy, crazily enough the Graphiti::Schema.generate technique above ultimately runs ::Rails.application.eager_load! which causes an application-wide class reload (I think) and when combined with the Rails development environment setting config.cache_classes = false causes an issue with the dry-events gem we're using (it throws a PublisherAlreadyRegisteredError error).

So while the technique above is great, I might have to go back to the directory introspection technique until I can figure out a solution for the dry-events problem. I'm discussing the issue on their support forum and will report back if I ever find a solution.

Maybe give Graphiti.resources a shot - should return the actual classes, though eager loading might still be an issue.

Thank you for the suggestion. I'd actually already tried that after looking up the definition for the earlier suggestion:

def self.generate(resources = nil)

It seems the eager load is required, as running just Graphiti.resources returns an empty set if the eager loading is not performed first. Well, that's the case in the Rails console, let me check the test environment...

Hmmm, it seems to work in testing. So maybe I'll roll with Graphiti.resources.reject(&:abstract_class?) for now and see how that goes. Thanks for making me re-check. 👍

Well, it worked in the test environment, but not in development*. The eager loading seems to be required there.

So I'm back to introspecting the file system until I can hunt down a solution for the dry-events problem. I'd link to that discussion but my post over there hasn't been approved yet (it's been over 24 hours now). 😞

*Edit: Ha! I got things working in development by adding the app/resources path to the config.autoload_paths setting in my applicatoin.rb file. So I think I'm back in business with the Graphiti.resources technique!

Edit 2: Ugh. After some time the Graphiti.resources solution went back to returning an empty set in development even though I am auto-loading the resource directory. It seems I just can't win. I'm going to have to go back to the file system introspection.

Edit 3: It seems the auto loading only requires the files when they are needed, and they are not needed early enough in my code to produce desired results. I looked into manually requiring all of the resources beforehand but this causes them to be loaded twice, with warnings about constants being already declared. So I looked into conditionally requiring them if they weren't already, but I did not find a good way of accomplishing that. Ultimately it all comes back to needing to look at the file system anyway, so I'm going to stick with my initial file system introspection shown in the second post above.

I'll reply with a link to the dry-events discussion when I get it, but really this issue is solved from a Graphiti point of view. There are decent techniques listed above for getting a list of all resource names using built-in Graphiti classes/methods.
(Then there is the file system introspection technique.)

So I consider this issue closed. Cheers and thanks! 😁