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

Generate Hal? #387

Closed
wants to merge 8 commits into from
Closed

Generate Hal? #387

wants to merge 8 commits into from

Conversation

benhamill
Copy link

I started playing around with subclassing ArraySerializer and Serializer that would help generate HAL JSON more easily. They're still pretty naive, but I've made enough progress that I feel pretty confident they could be done well. Is this something y'all'd be interested in putting in this gem, or should I think about making a separate one, probably with a dependency on this one?

@steveklabnik
Copy link
Contributor

I would be happy including something like that in the default, or making it
an external gem that we link to in the README.

@benhamill
Copy link
Author

I'll turn this into a pull request, then. I hit one thing so far that may require some changes to existing AM::S code (or at least be way easier that way), so that seems preferable to me. More details to come, after some commits. Thanks.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.23%) when pulling 2e34046 on benhamill:generate_hal into 919bb38 on rails-api:master.

_links.each do |rel, options|
method << " h[:\"#{rel}\"] = {\n"
method << " href: \"#{options[:href]}\",\n"
method << " templated: #{!!options[:templated]}\n" if options[:templated]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I was writing this into the actual project I'm working on, I had the links api working like this:

link :posts, route: :posts, template: '{?published_before,published_after}'
link :self, route: :post, params: [object.id]

And then the above code would use the :route option to build a url helper, passing :params and/or appending the :template as appropriate.

But this gem doesn't actually have a runtime dependency on Rails, so it seemed inappropriate to build that in, so now it takes :href and :templated (just like HAL links) and just passes them along.

Anyone have opinions on this aspect?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I think passing in the href here is the way to go. To that end, I wrote Zooplankton to aid in turning Rails routes into URI Template strings.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) when pulling 1eaef52 on benhamill:generate_hal into 919bb38 on rails-api:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.27%) when pulling 896edfe on benhamill:generate_hal into 919bb38 on rails-api:master.

@benhamill
Copy link
Author

I added code that will properly set up _embedded keys for has_one and has_many. That makes my above-mentioned self rel thing the only thing I have in mind to implement. Though, if someone spots something I've missed, I'm happy to add something else.

I am pretty happy with how easy this was to implement.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.04%) when pulling 374e643 on benhamill:generate_hal into 919bb38 on rails-api:master.

@benhamill
Copy link
Author

I've expanded how the link helper works (takes a block so you can interpolate attributes in or whatever). However, I'm still noodling on that 'self' link. I see a few different situations:

  1. It's a singular resource with a canonical place it lives, so you want to interleave in some identifier. When linked from somewhere general, it might be '/posts/{post_id}', but you need the specific id to make it '/posts/3'.
  2. It's a top-level collection resource without filters or anything, so you can use a static string. Think '/posts'.
  3. It's a top-level collection resource with filters or something, so you want to preserve params from the current request. When linked from elsewhere, it might look like '/posts{?page,author}', but when representing a specific response, would more properly be, say, '/posts?page=2&author=benhamill'.
  4. It's an embedded resource that needs to encode the relationship in it somehow. If it were linked from somewhere super-general, it might look like '/posts/{post_id}/comments', but when embedded in a specific post, it should be '/posts/3/comments'.

The bit about self links that I left in my README edits paired with my link helper should handle the first 3 cases, but the 4th one is a sticking point. Also, I'm not sure I've covered all the cases. Any suggestions?

@steveklabnik
Copy link
Contributor

Hey Ben,

I'm not interested in pulling this into master at this time. But, if you check out https://groups.google.com/forum/#!topic/rails-api-core/8zu1xjIOTAM, please note that I would like HAL to be in the 0.10 series, and we'd love a hand with that. Maybe some stuff from this PR can be used there.

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

Successfully merging this pull request may close these issues.

None yet

3 participants