2

I finished Ryan Bates #348 video for creating a JSON API using the rails-api gem. I have it working as in the example. However, in his example he has the page that calls the API in the same project. My goal is to separate out the client app from the API app.

I created a second rails app that simply includes the page that does a JSON request for the API data and a post when submitting the form. I have the client app running on localhost:3000 and the API running on localhost:4000.

Below is the client side code. It successfully submits a new deal record, but the GET doesnt load the list of deals. When looking in the logs it appears it is requesting it as HTML. When the page was apart of the same API project, the same code was making the call as JSON in the logs.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
  $(function() {
    function addDeal(deal) {
      $('#deals').append('<li>' + deal.name + '</ul>');
    }

    $('#new_deal').submit(function(e) {
      $.post('http://localhost:4000/deals', $(this).serialize(), addDeal);
      this.reset();
      e.preventDefault();
    });

    $.getJSON('http://localhost:4000/deals', function(deals) {
      $.each(deals, function() { addDeal(this); });
    });
  });
</script>

<div id="container">
  <h1>My Deals</h1>
  <form id="new_deal">
    <input type="text" name="deal[name]" id="deal_name">
    <input type="submit" value="Add">
  </form>
  <ul id="deals"></ul>
</div>
Nat Ritmeyer
  • 5,634
  • 8
  • 45
  • 58
Paul Sylling
  • 359
  • 1
  • 5
  • 12
  • "it appears it is requesting it as HTML" - what do you mean by that? The `$.getJSON` only makes a request and expects to get JSON back, it does not "ask" the server for JSON contents AFAIK, it takes whatever the server sends back and try to interpret as JSON (or maybe errors if the mime type is wrong). (P.S. your `post` call OTOH is not specifying any dataType as the 4th parameter) – mgibsonbr Aug 26 '12 at 21:55
  • The comment about requesting as HTML is from Terminal. In Rails I can see the log of what was requested and it says Processing by DealsController#index as HTML and when they were both in the same app it was Processing by DealsController#index as JSON – Paul Sylling Aug 26 '12 at 22:59

1 Answers1

2

Because of Cross Origin Policy you have following options:

  1. Use jsonp (don't do this since you have your server :) check below )
  2. Manage Cross Origin Resource Sharing on server, recently I wrote answer here how to achieve this
  3. You could use rails ActiveResource::Base to conect to your api, but it may be slow, and you would repeating yourself unless there is some presentation logic you need on backend. BTW, check Nibbler gem it may be somewhat better... it really depends what you need to do in backend.

Anyhow. I would avoid approach 1, its kinda overhead especially if you want to POST, PUT or DELETE, and you can allows use option 2 if you have pure javascript app running as UI. But even if you are building JS agnostic app you always need a bit of backend processing so option 3 is probably something you'd prefer.

Community
  • 1
  • 1
Milan Jaric
  • 5,556
  • 2
  • 26
  • 34
  • So by using activeresource in the other app, it gets by the cross domain policy? – Paul Sylling Aug 26 '12 at 23:01
  • Cross domain policy only applies to browsers, activeresource will not suffer from it. – Milan Jaric Aug 26 '12 at 23:53
  • Do you think it would be a bad idea to have the api at domain.com/api rather than doing a subdomain and having these limitations? – Paul Sylling Aug 27 '12 at 00:14
  • If you want to offer your api to third party, then go with subdomain, you will need first folder in path for version (probably), but that is not must. It is all about how you prefer to make resource links – Milan Jaric Aug 27 '12 at 00:28
  • You have been very helpful. Thanks. One last thing. So if I were to offer this API to third-parties, would they have to use JSONP since they would encounter the Cross Domain as well – Paul Sylling Aug 27 '12 at 00:31
  • Yes if they are using javascript in browser. but you can set in your web server CORS configuration as described in point 2 above, so they can use ajax calls instead, or even if you set wildcard in configuration then it would work for everyone. Please note JSONP is OK if you don't have to do POST, DELETE or PUT in request, so if it is just querying data you don't have to bother with special configuration – Milan Jaric Aug 27 '12 at 07:20