Custom REST method to a Model

When defining a Model using superMap or baseMap how to add a custom method other than CRUD?

For example previously,

var post = can.Model.extend({
  "find": function () { }, // my overrode behavior
  "publish": function () { } // my custom code to AJAX call to `/api/post/publish`
});

What is the correct way to write publish method now given it has to call a different URL.

Having other ajax methods besides the standard get / getList / save / destroy should be avoided. I’ve seen people do this, and generally speaking, it’s better to conform to that interface, even more so with can-connect because other behaviors won’t interface with those “expando” methods (combine requests, fall-through cache, real-time).

In your example, I’d change things so there’s a published: false property that when set to true actually publishes the article. That way .save() can work just fine.

If you MUST do this, then just add these to your Map as you would your Model:

Map.extend({
  ...
},{
  ...
})

connect.baseMap({
  Map: Map,
  ...
})
1 Like

Thanks Justin.

I am convinced and want to avoid creating my own methods.

But, how can we create Models that call REST methods other than CRUD? get, getList, save make calls to GET /post/{id}, GET /post, POST /post and PUT /post/{id} respectively. But how to make post Model call say, GET /post/{id}/comments?

With data/url you can write it like:

url: {
  createData: "/post/{id}/comments"
}

Or you can provide your own createData function.

Thanks Justin.

But I already have createData function.

var postsConnection = connect([
  require("can-connect/data/url/url")
],{
  url: {
    getListData: "GET /posts",
    getData: "GET /posts/{id}",
    createData: "POST /posts",
    updateData: "PUT /posts/{id}",
    destroyData: "DELETE /posts/{id}"
  }
});

Adding a new method in URL object did not work, like,

....
url: {
   ...,
   reactionsForPost: "GET /posts/{id}/reactions",
}

And it brings me back to my initial question on how to call a custom URL other than CRUD.

You do it like you did before, just in the Map:

Post = Map.extend({
   "publish": function () { } // my custom code to AJAX call to `/api/post/publish`
},{

})
1 Like