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

Nested resource URLs #11

Closed
Emerson opened this issue May 5, 2016 · 12 comments
Closed

Nested resource URLs #11

Emerson opened this issue May 5, 2016 · 12 comments

Comments

@Emerson
Copy link
Collaborator

Emerson commented May 5, 2016

@themarkappleby pointed out an issue that we need to figure out – especially since it's a valid JSON-API convention.

When fetching a resource, it's perfectly valid to do so through a nested URL, you can see a clear example of this articulated in the specification here.

And the following request fetches an article’s author:
GET /articles/1/author HTTP/1.1

Right now, our find calls just accept the name of the model jsonApi.find('author', 1)... so what's the best way to support this feature?

@themarkappleby was thinking we could parse a raw string jsonApi.find('articles/1/author'), but I'd be a little worried about model names vs urls and figuring out how to map all that back.

I was thinking we could maybe pass an object in some instances:

jsonApi.find({model: 'author', url: 'articles/1/author'}, 1)

Or maybe an options object?

jsonApi.find('author', 1, {nested: 'articles/1'})

Happy to hear any thoughts about this – @derek-watson I know you are questioning the requirements of having defined models all together (I still need to respond to that)

@derek-watson
Copy link
Contributor

derek-watson commented May 5, 2016

Restangular does a nice job of expressing nested resource relationships, but they're able to do it because they separate the resource definition from the action in separate methods:

https://github.com/mgonto/restangular#url-building

Devour's solution to the example above might be

jsonApi.find('articles', 1).find('author').get()

Methods like find and findAll would return a reference to a resource, and you'd have to choose what action you wanted to take with it by adding a call to get, post, patch or destroy.

@Emerson
Copy link
Collaborator Author

Emerson commented May 5, 2016

Yea, that's what I was saying to Mark... would love to have that pattern, would be a fair amount of work to implement I think

@derek-watson
Copy link
Contributor

I updated my comment after you replied with more detail :)

@Emerson
Copy link
Collaborator Author

Emerson commented May 5, 2016

Feeling like we should take things in that direction, so so nice.

@derek-watson
Copy link
Contributor

derek-watson commented May 5, 2016

If we do, it might make sense to rename some of the methods that describe resource locations, as they'll be used for multiple actions. For example,

Before:

// To find many...
jsonApi.findAll('post')

// To find many with filters...
jsonApi.findAll('post', {page: {number: 2}})

// To find one...
jsonApi.find('post', 5)

// To create...
jsonApi.create('post', {
  title: 'hello',
  content: 'some content',
  tags: ['one', 'two']
})

// To update...
jsonApi.update('post', {
  id: 5,
  title: 'new title',
  content: 'new content',
  tags: ['new tag']
})

// To destroy...
jsonApi.destroy('post', 5)

After:

// To find many...
jsonApi.all('post').get()

// To find many with filters...
jsonApi.all('post').get({page: {number: 2}})

// To find one...
jsonApi.one('post', 5).get()

// To create...
jsonApi.all('post').post({
  title: 'hello',
  content: 'some content',
  tags: ['one', 'two']
})

// To update...
jsonApi.one('post', 5).patch({
  id: 5,
  title: 'new title',
  content: 'new content',
  tags: ['new tag']
})

// To destroy...
jsonApi.one('post', 5).destroy()

@Emerson
Copy link
Collaborator Author

Emerson commented May 5, 2016

If anyone feels the will to work on this, I dropped a branch we can hack on:

https://github.com/twg/devour-jsonapi-client/tree/feature/resource-locations-refactor

@billxinli
Copy link
Collaborator

So we are basically copying Restangular's style?

@Emerson
Copy link
Collaborator Author

Emerson commented May 5, 2016

@billxinli I think that's the idea – but open to hear any thoughts

@billxinli
Copy link
Collaborator

I used Restangular before and quite liked it. I might take this and give ES6 a spin. Curious on the backend/browser support this library will have?

@Emerson
Copy link
Collaborator Author

Emerson commented May 5, 2016

Would love for this to work in both node and in browser, although I'd assume that its primary use will be in browser. I don't have any strong opinions about supported node versions, so ¯\\_(ツ)_/¯

@billxinli
Copy link
Collaborator

Should the builder method allow the following?

var jsonApi = new JsonApi({apiURl: 'http://example.net'})
jsonApi.get() // GET http://example.net/ 

Here we are assuming / is a resource of some sort.

@Emerson
Copy link
Collaborator Author

Emerson commented May 6, 2016

This has been resolved 🎉

@Emerson Emerson closed this as completed May 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants