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

Add best practices for building Ruby JSON APIs #365

Closed
wants to merge 6 commits into from
Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions best-practices/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,14 @@ Angular
[annotations]: http://robots.thoughtbot.com/avoid-angularjs-dependency-annotation-with-rails
[ngannotate]: https://github.com/kikonen/ngannotate-rails
[angular-translate]: https://github.com/angular-translate/angular-translate/wiki/Getting-Started#using-translate-directive

Ruby JSON APIs
--------------

* Follow Heroku's [HTTP API Design Guide]
* Use a fast JSON parser, e.g. [`oj`][oj]
Copy link
Contributor

Choose a reason for hiding this comment

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

Oj out of the box doesn't do exactly what you might expect:

irb(main):004:0> puts Oj.dump(foo: 'baz')
{":foo":"baz"}

I'd add a note here that for Ruby hashes w/ symbols you need to enable compat mode.

irb(main):005:0> Oj.default_options = {:mode => :compat }
=> {:mode=>:compat}
irb(main):006:0> puts Oj.dump(foo: 'baz')
{"foo":"baz"}

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like for Rails 4.1~ there's a new gem that can be included:
https://github.com/ohler55/oj#compatibility

gem 'oj'
gem 'oj_mimic_json'

Copy link
Author

Choose a reason for hiding this comment

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

@harlow good to know, thank you! I went ahead and merged this as-is but will see about expanding the recommendation to use oj to include some caveats about its usage in a separate PR.

* Write [request specs] for your API endpoints

[HTTP API Design Guide]: https://github.com/interagent/http-api-design
[oj]: https://github.com/ohler55/oj
[request specs]: https://www.relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec
Copy link
Contributor

Choose a reason for hiding this comment

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

If we're using an in-app JavaScript client as the primary consumer of the API, have we generally done this? Many of the applications I've seen rely on Capybara feature specs to make sure the controllers/requests are working.

Copy link
Contributor

Choose a reason for hiding this comment

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

If the JSON Api is being consumed by something else "in process" then I agree. If your ultimate deliverable is the JSON API, then the request specs are the edge.

Copy link
Author

Choose a reason for hiding this comment

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

@jferris, @derekprior -- great point. I agree. I modified this bullet point accordingly in 3e2c9db.