Data: [JSON API] Can't use queryRecord for single resource

Created on 28 Jul 2015  路  20Comments  路  Source: emberjs/data

Currently with findRecord you can request items like /items/:ID. There seems to be no option for any query parameter.

When you do the same with the new queryRecord method you get a request like /items?id=:ID and you can include other query paramaters like include. There seems to be no option to include the ID like with findRecord in the new implementation of queryRecord in ember-data 1.13.7.

JSON API seems to state that it should be requested like /items/:ID?include=other_items which is not currently possible.

Most helpful comment

How about fields query parameter? It seems to me that we should have ability to use it the same way as include parameter as it is also described in JSON API specification and it makes sense to use this parameter while finding a single record.

So don't we need to add ability to use fields query parameter out-of-the-box without overriding some methods?

All 20 comments

I found that overriding buildURL in the adapter like this works:

buildURL: function(model, id, snapshot, requestType, query) {
  this.get('host') + '/myModel' + query.id;
}

then you can do queryRecord('myModel', {id: 1, myParam: 123})

A workaround until a better way comes along.

I'm overriding buildURL in the adapter like this:

    buildURL: function(modelName, id, snapshot, requestType, query) {
        if(requestType === 'queryRecord'){
            var url = this._buildURL(modelName, query.id);
            delete query.id;
            return url;
        } else {
            return this._super(modelName, id, snapshot, requestType, query);
        }
    }

You can use it like this.store.queryRecord('modelName', {id: 12345, otherQueryParameters.... }).

After adding the id to the URL it removes it from the query so it doesn't end up in the query parameters as well.

@nickschot I was going to suggest you could override urlForQueryRecord instead of buildURL to make it a bit easier but apparently that hook is missing (#3607). So yeah, thanks for making me find that out :)

@wecc Indeed! That would be a better/cleaner option. I guess #3607 shouldn't (immediately) include a fix for the ID problem as it would be best if the actual queryRecord would accept an id as argument instead of getting it from the query.

It does seem like queryRecord should accept an id as an explicit argument to make it equivalent to findRecord and peekRecord. Because this is not present fairly normal JSON API calls can't be made, such as fetching a singular resource and sideloading relations, e.g. /posts/10?include=comments.

The whole reason for queryRecord is to _not_ require an ID. To be able to find a resource by slug, token or some other arbitrary request.

I was chatting with @thaume earlier about this and got the feeling it's not really queryRecord not accepting an ID that's the issue, it's more that it's hard to pass query params to findRecord. Would that be a correct assumption?

@wecc yes that seems reasonable, if we could pass query params to findRecord easily that would solve this use case too.

That'd be even better, yes.

As a workaround you should be able to use adapterOptions in findRecord() to provide query parameters to urlForFindRecord().

store.findRecord('type', 123, { adapterOptions: { query: { foo: 'bar' } } });

Then override urlForFindRecord() in your adapter with something like:

urlForFindRecord(id, modelName, snapshot) {
  let url = this._super(...arguments);
  let query = Ember.get(snapshot, 'adapterOptions.query');
  if (query) {
    url += '?' + Ember.$.param(query); // assumes no query params are present already
  }
  return url;
}

Thanks for the recommended workaround. Works here.

Works for me too (Ember and Ember Data 1.13.7), thank you!

Although @wecc 's solution seems to work for simple cases, when I tried to implement it with a findRecord call inside a promise success to a findRecord call, it did not work. I pulled the same request outside the then success and it worked fine. Just a warning... I had to go the route of making the API somewhat non RESTful and just doing something like 'api/post?id=1&showComments=true' and using queryRecord

@bmac I think this could be closed as 'won't fix, according to your answer here

I am going to close this issue as queryRecord has been overhauled in #4300: queryRecord should be used when the id of the record is NOT known beforehand. In all other cases use findRecord instead.

Also, support for the include query param has been implemented via the ds-finder-include feature which has been introduced in #3976 and is available since 2.5.

As pointed out by @sly7-7 above, the comment @bmac made in https://github.com/emberjs/data/issues/4156#issuecomment-183740105 should provide further context on which method should be used when.

If you really need custom query parameters for queryRecord or findRecord, you'd need to overwrite the corresponding urlForXXX methods, as pointed out by @wecc in https://github.com/emberjs/data/issues/3596#issuecomment-126604014.

How about fields query parameter? It seems to me that we should have ability to use it the same way as include parameter as it is also described in JSON API specification and it makes sense to use this parameter while finding a single record.

So don't we need to add ability to use fields query parameter out-of-the-box without overriding some methods?

@pangratz I agree with @poohitan, I just ran into this issue where I wanted to provide fields option to findRecord and found that I could not. This seems like a missing feature.

This seems like a very low impact, easy addition. Moreover, w/ includes we cover the problem of "under-fetching" and with fields, we then can cover the problem of "over-fetching". I'll put up an issue!

This seems like a very low impact, easy addition. Moreover, w/ includes we cover the problem of "under-fetching" and with fields, we then can cover the problem of "over-fetching". I'll put up an issue!

Interesting how this came back into view after 5 years 馃槄

Better late than never !

Was this page helpful?
0 / 5 - 0 ratings