Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate more powerful mechanisms for generating complex resources #30

Open
theninj4 opened this issue Mar 31, 2016 · 5 comments
Open

Comments

@theninj4
Copy link
Contributor

Right now we can build up resources like this:

var aPromise = client.create("articles")
  .set("title", "some fancy booklet")
  .set("content", "oh-la-la!")
  .relationships("tags").add(someTag)
  .sync();

The someTag Resource needs to exist prior to it being added to a relationship, which means there's an amount of promise scaffolding required to build up complex scenarios.

This issue is here for us to openly discuss options that enable both client-side implementations and server-side implementations to most effectively build up complex resources without imposing limitations on either.

@theninj4
Copy link
Contributor Author

@holidayextras/frontendguild - all thoughts are welcome. I'm also open to the idea of some clear documentation around the most effective way to utilise this library.

@hpoom
Copy link

hpoom commented Mar 31, 2016

What are your thoughts on how people might use this client alongside Angular, Backbone, or Ember etc?

I ask because I can see great use cases for this client if no existing client framework is being used, or for server side rendering solutions, but for Angular for example, I would expect to see somebody modify it's existing baked in ajax model fetch, update, delete code. I think what I am saying is on the client I would expect to see angular-jsonapi-client and backbone-jsonapi-client.

Regards "most effectively build up complex resources". I need more time to think about this. One way looking at ORMs as a guild might be to define a number of new resource that are related into a transaction, and then sync that transaction so that write happen all together. If that is even possible (might be data store specific?)

I will think more on the relationships and comment again soon.

@theninj4
Copy link
Contributor Author

theninj4 commented Apr 1, 2016

My priority list in terms of what we would need looks like this:

  1. How could we better interact with it via NodeJS?
  2. How could we better interact with it when using React?
  3. How could we better interact with it via a Backbone model?

I like the idea of interfacing with existing frameworks model layers, it sounds pretty straight forward (I'll probably regret that statement!) and it leaves the question of "how do we make models easier to work with" up to the framework ecosystem and/or developer.

I know a few people around the office have been keen to try GraphQL for accessing complex models (https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html) - which could be an interesting wrapper to add around this module.

It should also be possible to take a nested JSON object and convert it into a network of related models, which is another option.

Supporting some kind of sql-database-esque transaction is also a possibility and could ease the creation of lots of sequential models.

I'd love to hear what some of our other devs think, especially from those who spend most of their time writing frontend JS. I'm not looking for a solution, just ideas on what some good syntax could look like.

Theoretically we might be able to get this working:

it("could use transactions", function(done) {
  var transaction = client.beginTransaction();

  var someTag;
  client.find("tags", { }, transaction).then(function(allTags) {
    someTag = allTags[0];
  });

  var newArticle = client.create("articles")
    .set("title", "some fancy booklet")
    .set("content", "oh-la-la!")
    .relationships("tags").add(function() { return someTag; })
    .sync(transaction);

  someTag.fetch("articles", transaction).then(function() {
    assert.equal(someTag.articles[0], newArticle);
  });

  newArticle.delete(transaction);

  transaction.commit(function() {
    done();
  });
});

@theninj4
Copy link
Contributor Author

theninj4 commented Apr 1, 2016

@matthewfl perhaps you'd like to throw in your two cents?

@matthewfl
Copy link

Hi @theninj4

Some of main things that I had in my jsonapi client were basically "overloaded promises" that allow you to easily access fields on objects and having a way that all methods can take a promise in place of a value.

In your example above this would maybe change to something like:

var someTag = client.find("tags", {}, txn).get(0);
// ...
...add(someTag)

Since this would be a promise, you would be guaranteed that the add would operate after someTag has been loaded, whereas now it isn't clear to me that someTag will actually be loaded before add fires (race condition?). Additionally, you would save on the extra two functions to .then and .add.

For overloading the promises, if you know what entries are going to be on an object you can have something like: someTag.articles.then(...) instead of using a .fetch method.

Orthogonal to the above, if you do decide to add transactions, would you consider maybe binding objects to a given transaction so you don't have to keep passing the transaction to all methods. eg:

var txn = clinet.txnBegin();
var obj_on_txn = txn.create("some name", .. ...);
//...
obj_on_txn.articles.then(...);

Also, for the .relationships method, that isn't immediately clear to me what that is returning, is it a promise of just the relationships of an object, or that specific field. Then if I perform a .sync on that returned object what am I actually syncing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants