Grapher - Collection Relationship Manager + GraphQL Like Data Fetcher


#62

Okay, there’s something very weird going on.

If I do this:

const query = createNamedQuery('allUsers', {
    users: {
        username: 1    
    }
});

then I do indeed get all users.

If I do this:

const query = createNamedQuery('allTasks', {
    tasks: {
        name: 1    
    }
});

then I get an error Error: We could not find any collection by the name tasks even though the tasks collection does exist in the database


#63

Okay, found it. All this importing stuff from /imports makes it damn hard to see what is imported first.

I’ll see if I can create a much simpler example tomorrow with what I’ve learned. Something of the size of the counter example, maybe.


#64

I am now complaining about the lack of simplicity in grapher also :slight_smile: Based on feedback it’s confirmed that it is not that simple. Please come-up with solution to make it better, or state directly what makes it harder for you, so I can have at least some idea of what’s so hard to understand. Otherwise it’s just called “whining”


Apollo(GraphQL), React, Facebook's BSD + Patents. Shouldn't we be worried?
#65

Ok, the reason for “Tasks” not existing is because the collection needs to be loaded and registered as Mongo.Collection. Bc the query tries to search a “Tasks” collection and if it doesn’t find it breaks.

  1. Better error "We could not find a collection by the name “tasks”, make sure you imported it before creating the namedQuery

So we need to specify the loading orders:

  • What we can do is what we did for createQuery, like Tasks.createNamedQuery(“allTasks”, {title: 1}, I remember I had a very good reason why I did not do it so. But will investigate.
  • Links should be loaded separately from collections. The reason they are not put in the same file is because you can have Users -> Comments link and Comments -> Users inversed link. Interdependency loop, and makes the “Collection” look like { __esModule: … }, and we need the real one when adding links.

Cheers man. Very good feedback.

We should have a “Get started” guide in the docs section explaining this. I’ll be working soon on this.


#66

The obvious solution to the Interdependency loop problem is to have collections looked up by name. You already need this when collections are referenced as keys. Also it makes it easier to generate links dynamically from data.


#67

I have updated the README.md (Added current architecture + description)
I made some small changes to the structure to make it more clear
I commented out everything in grapher to describe it in depth.

Please tell me if it’s clearer. Thank you!


#68

@gunn I truly appreciate your solution, thing is that was how it was first thought put a String instead of a Collection object. And lazy-load later on. However, we wanted to avoid that because it violates the modular approach principles. This is how we actually did it in “Quantum Framework” when in Meteor 1.2.

Dynamic Links ? That’s one bad-ass concept. I’ve yet to see the aplicability of it, but it sounds very cool! If the community will want this, we’ll think of a way. Until then, we keep it like this, for the sake of explicity.

The main reason we allowed stuff like:

createQuery({
     users: { firstname: 1}
})

Is to allow testing using Grapher Live. But we found out it’s pretty catchy and we should also allow it like this, but see what @rhywden encountered ? The exact thing we were afraid of, “no collection found”, because collection was not loaded, so query could not be created.

We turned this problem on multiple sides, and unfortunatelly, that’s the best way to do it :), it’s not that big of a problem, because you still keep “links.js” near the collection, so concerns are properly separated, it’s just that the loading order differs.

There are at least 5 other reasons of why collections should exist as objects when links are created, it’s related to data consistency and “autoremove”.

Cheers!


#69

Realky great job! Thank you, @diaconutheodor, and your team.
Just one question, does your api has an option to use or not use reactive joints?


#70

@kvetoslav


If you subscribe to a query, it will morph into a reactive query meaning you can just do fetch(), however, if you use createQueryContainer (from grapher-react), you have the ability to specify {reactive: true} or {reactive: false} :wink:

Cheers!


#71

Thanks so far with the feedback guys, you’ve been really helpful. And thank you for the encouragements, got a bit of an ego-boost.

new Promise('I will create a grapher video tutorial explaining everything from zero to advanced')

OFF TOPIC:
Right now my focus is on Meteor Tutorials, get the first chapter going, create the laracasts for Meteor and create hysteria for Meteor again. A lot of people last year quit Meteor before introducing modular approach and integration with React. Which together with Grapher (ofcourse), and Flow Type (maybe) finally makes it ready for the large scale.

We lost some good guys along the way. Our plan is get them back, and bring new guys in as well. Idea is to make them realize that this platform is trully great.

ON TOPIC:
After analyzing our business requirements in depth we realized we need 2 more things to grapher:


The conditional reactivity graph… oh boy I have no idea how to even begin thinking about it. I left an API candidate there. Thing is, by experience I realized that everything is possible when you are programming, but first you need to get the API right first, the “what”, then think about the “how”.

Feel free to comment your wildest ideas.
Cheers


#72

This is great, thank you very much for your explanation.


#73

Please, for the love of Glod, no tutorial video.


#74

Why not ? :slight_smile: It’s not as if I’m filming myself. Please be descriptive :slight_smile: (This does not mean “text” documentation should be ignored)


#75

Because tutorial videos only really make sense for stuff that you need to visualize - like movements in the three-dimensional space or propagation of waves or relationships between models.

But programming is based on text. It’s a bad candidate for visualization. I know that it’s terribly en vogue right now to make videos left and right but in my opinion as a teacher you have to think about why you’re using the medium you’re using. And whether it’s actually a good fit for what you want to show.

With a text-based tutorial, you can easily “pause”, you can easily skip forward and you can just as easily go back in case you missed something.
That’s not something you can do with videos - I know that I’m always frustrated by questions like: “So, where did he explain that concept?” or “What was the syntax he used again?”

Hell, with plain text I can even use the Search feature of browsers to search for keywords I remember on the page. I can copy&paste easily.

And so on and so forth. Again, I have nothing against videos in general. I just think they make a poor fit for explaining programming concepts of a framework. Explaining sorting algorithms? Fine. Explaining how IoC works? Also fine. But coding? Nope.

There’s also the question of speed, by the way.


#76

Video tutorials would be super awesome. Thank you so much. Really looking forward to it.

Cheers!


#77

Here’s a good example of how to do it:


#78

I really thought you were just trolling, but you raised some very enlightning arguments.

The thing is I personally learn code by checking text, the “HTML” tutorial can still have vizualizations & images, it can have a very nice table of contents that you can access, and you can easily skip some parts you already know, you can come back later to it, without having to “skip the video to where you left of”. You can copy paste chunks of code, you can search keywords. You can pause scrolling to digest what was said…

Holly sh**. You can improve the tutorial without having to reshoot the video.

I mean you can make it fun & engaging via what HTML & JS has to offer… However some people would prefer video tutorials bc they are more personal, but this only applies to very charismatic people, with my eastern european russian-like accent I doubt charisma is my strongest suit. :laughing:

Too bad I kinda promised the community Video Tutorials on Meteor, but I believe as long as I find a nice innovative and super friendly way to deliver these tutorials they may forgive me, as long as I do a freaking good job.

I did not make a descision yet, I’ve yet to ponder on it. But, heck, you’re right.


#79

Well, my arguing style sounds aggressive (though I prefer the word “forceful”) because half the time I’m actually arguing with myself (and I’m my biggest critic).

Which means that if you raise a valid point I’ll certainly consider it. It only sounds like my opinions are set in stone :slight_smile:


#80

Haha, no worries, I actually thought few moments ago “this guy has a bit of an aggresive style, but he has valid points, I care about arguments so the way he expresses them is not relevant.”. I encourage everyone who has an opinion to state it based on logical statements, even if it may sound too direct/opinionated, or they may be “wrong”, this is how great ideas are crafted, one person does not hold all the answers, but together we are more than our sums.

Now, just to go ontopic again:
If anyone has any suggestions for Grapher. Things are not set in stone. It’s a bit opinionated how the API was built and how you should do things, but the reason is that it was very very well thought, through and out.

Some crazy candidates:

// NOT IMPLEMENTED IN GRAPHER (THESE WERE JUST OTHER API FORMS WE HAD TO PICK FROM)
// query:
[
    'users', [
           'profile': 1,
           'posts', [
                'comments', [ ... ],
                'title'
           ]
    ]
]

And for linking data:

// NOT IMPLEMENTED IN GRAPHER (THESE WERE JUST OTHER API FORMS WE HAD TO PICK FROM)
// links via collection _.transform function
user.posts().add(post)
user.posts().fetch()
user.posts(filters, options).fetch()

Anyways, feel free to state your ideas, and your needs for Grapher. I take it seriously into consideration.


#81

Just a small FYI:

Exposure.restrictFields(filters, options, ['profile']);

doesn’t seem to work on the Meteor.users collection. Filtering, on the other hand, does work.