Building complex REST url

In my ember application I have 3 models (User, Client, Product), to get purchased product info I have to call a REST api url as:

purchasedproducts.php?action=viewProduct&username=michael&password=123456&clientID=2&productID=201

My question now is how I can build this URL in ember to invoke the REST Get call?

Thanks

I don’t want to upset you but it’s not a REST api. RESTful services support only GET, PUT, POST, PATCH methods and so on without any action params. It’s a very big difference. However you can do the following way:

App.ProductAdapter = DS.RESTAdapter.extend({
    // request to find some products
    // `query` it's your query parameters
    findQuery: function(store, type, query) {
        query.action = 'viewProduct';
        return this.ajax('/purchasedproducts.php', 'GET', {
            data: query
        });
    },
    .... other CRUD methods
});

and then

this.store.find('product', {
    username: "michael",
    password: "123456",
    clientID: "2",
    productID: 201
});
1 Like

Thanks for taking the time to help, appreciate it. Is it possible to do the same with POST? I mean to have custom adaptor to handle custom data sent in POST requests?

Thanks

You can add custom methods in the same one adapter.

App.ProductAdapter = DS.RESTAdapter.extend({
    someCustomMethod: function(customData) {
        // Here you can handle custom data, and after that send POST request
        return this.ajax('/ajax.php', 'POST', { data: customData });
    }
});

… usage

var customAdapter = this.container.lookup('adapter:product');
var data = {
    username: "michael",
    password: "123456",
    clientID: "2",
    productID: 201
};
customAdapter.someCustomMethod(data).then(function(response) {
    // response handler
}, function(e) {
   // error handler
});

But I’m not sure that it’s exactly what your need. And are you really use Ember Data or not?

2 Likes

@midd you should be extending buildURL, to create custom urls for your models.

@knownasilya You mean override or literary ‘extend’ like .extend?

Instead of overriding findQuery, like he did above, I’d override buildURL instead, since the other methods use it, and you wouldn’t have to override the other query methods, if you needed to use those.

@knownasilya Any chance you can please point me or show me an example of buildURL overriding?

Thanks

Have a look at the code for buildURL first, this will give you an idea of how it’s used.

The result of buildURL is appended to the host and namespace values.

App.ApplicationAdapter = DS.RESTAdapter.extend({
  host: 'localhost',
  namespace: 'api',
  buildURL: function (modelType, id) {
    return 'hello-' + this.pathForType(modelType);
  }
});

The resulting url for user model, would be localhost/api/hello-users

@knownasilya Great, but now the problem will be that all Post/ Get URL’s are overridden with the new overridden buildURL which is not good as I have different URL for Get and another for Post each model in the emberjs app.

Unless you have a suggestion on how to change the URL based on each model being loaded / saved through the RESTful ws…In other words I will need to have a specific URL for each model Get and Post? Thanks in advance for your time and sharing your experience in this part

don’t want to upset you but it’s not a REST api. RESTful services support only GET, PUT, POST, PATCH methods and so on without any action params. It’s a very big difference.

Eventhough its anti-pattern I’m facing this kind of challenges quite often(not necessarily action params, but custom ajax methods to aggregated data from the server). What is the recommended approach? I only can think of aggregating them on the client side, which is much dirtier way in many cases.

@midd What I exactly trying to do here is to implement this 2 JQuery Post/ Get calls to an API, the first authenticate the usage of the API and the 2nd shall pull data from the server through the API…I’ve spent hours trying to figure out how to implement them in my Emberjs app but with no clue, so if you can help that will be really great…thanks in advance

To auth the usage of the API:

 $.ajax
  ({
    type: "POST",
    url: "http://portal.domainname.com/auth",
    dataType: 'json',
    async: false,
    data: JSON.stringify({ 
        Login: "logmein@email.com", 
        Password : "test"
    }),
    success: function(data) {
        console.log(data); //Here I get the token needed for further calls...
    },
    error: function(xhr, error){
        console.debug(xhr); console.debug(error);
    } 
});

The following shall load data in employee model:

$.ajax   ({
    type: "GET",
    url: "http://portal.domainname.com/employees",
    dataType: 'json',
    async: false,
    beforeSend: function (xhr) {
        xhr.setRequestHeader ("Token", "0000000-0000-0000-0000-00000000");
    },
    success: function(data) {
        console.log(data);
    },
    error: function(xhr, error){
        console.debug(xhr); console.debug(error);
    }  });

I understood container.lookup is deprecated hence its not intended to be a public API. Has anything changed or am I misunderstanding?

I completely agree with you that it looks like a hack, but sometimes it becomes very useful.