dchester / epilogue

Create flexible REST endpoints and controllers from Sequelize models in your Express app
846 stars 116 forks source link

Ember-data interoperability #121

Open jellelicht opened 8 years ago

jellelicht commented 8 years ago

It seems disproportionately difficult to get epilogue to play nicely with Ember-data without jumping through some major hoops on the client side of things. Which milestones would be relevant to hook into in order to make both data from epilogue and data that flows into epilogue compliant with what Ember-data expects?

mbroadst commented 8 years ago

@wordempire it would be incredibly helpful if you could provide more information about what Ember-Data expects. I've never used that before.

jellelicht commented 8 years ago

My apologies for the late reply. I'll try to give some examples and references later this week describing what I'm talking about

mikemimik commented 8 years ago

I would be very interested in this as well. I understand the difficulty that @wordempire is having. I myself had to hack ember to make what I was getting from my API (epilogue driven) to work 'nicely' with each other. I however am no ember expert and it's been some time, so I'm unfamiliar with what ember data expects as well.

mbroadst commented 8 years ago

@mikemimik it would be really helpful to know what you had to hack on the ember side of things. I'm sure this is a very simple problem to solve, we just need a list of what's required

mikemimik commented 8 years ago

@mbroadst I don't recall exactly what I had to do. I do recall having to make two separate calls to my API (epilogue driven) to get the bits of data because of the way ember data wanted to deal with embedded or included model data. I'll have a look over the holidays about this. I would like to start working with ember again very soon.

mbroadst commented 8 years ago

it looks like the main observable difference (from glancing at the docs for the rest adapter) is that returned results have root objects. Where we simply return the object itself (in a singular case), or array of objects (in the plural case), they prefer a top level object key to deal with.

Another issue is that we distinguish between plurality of endpoints (update: /person/123, create: /people), where they only use the plural form. Not a big issue here, we already allow customization of this behavior.

In both cases these are very easy to get around (a single middleware could do all of this), but in sure there are missing pieces yet. I'll put together a branch to play around with issues we find and see if we can get some level of support, let's keep findings confined to this ticket.

JasonWeh commented 8 years ago

I am interested in using this with ember-data. Total noobie with nodejs. @mbroadst you are right about root objects I am going have crack at creating middleware that inserts the root object. See how go. Part me wonders if milestone could also solve this problem

JasonWeh commented 8 years ago

Ok I have no idea how can use middleware to add root objects. I can see data written within context.instance but have no idea how can change this so now contains route object. Before found this library started writing routes with rectify for all my models. I had same problem with ember data. To solve if made this simple change from res.json(products); to this res.json({products}); As result now had route node now has name. Then could use data within ember.

Think going to go back to my simple restify server. If anyone could help with issue love idea of not having to write same code for all my modules

mbroadst commented 8 years ago

@JasonWeh the middleware would look something like this:

resource.list.write.before((req, res, context) => {
    let endpoint =
      (Array.isArray(context.instance)) ? resource.endpoints.singluar : resource.endpoints.plural;
    let tmp = context.instance;
    context.instance = {};
    context.instance[endpoint.name] = tmp;
    return context.continue();
});

This is obviously sample code, as there is no name associated with the endpoint class, I just used that as an example of where you might grab a singularized/pluralized version of the name of the type being returned. As you can see, this is not very difficult.

In fact, another way to do this from a higher level is simply to override the base controller classes send method.

What I would probably do is put together a milestone middleware (e.g the declarative style of defining middleware a an object): let emberSupport = { list: { write: { before: function(...) } } } and then resource.use(emberSupport))