+2  A: 

Hello,

I think the best solution for you is to merge your first two points.

I suggest using JSON instead of XML: the only point in favor of XML is XPath which is useless in returned data. JSON leads to better response time (and more readable data for better debugging ! :p). Plus, most languages can read JSON. For instance, PHP can natively parse JSON to array/object with json_decode, so it's a nice point. ;)

For controllers, you can namespace it but it's not an obligation, maybe it's better in certain cases to avoid fat actions with tons of conditions. With the Rails 3 router, the separation of API calls in a subdomain (api.webapp.com) is trivial).

For the model, sure you should use the same as used in the whole application.

The new rails router syntax is sugar, you will enjoy. Good luck & have fun! :)

Sephi-Chan
All languages have bindings to work on XML. XPath is a nice way to query a returned response. Your assertion that JSON leads to better response time is useless: not based on facts. JSON has the same duplication that XML suffers from. Both are highly compressible using gzip, which is what should be done.
François Beausoleil
+4  A: 

I would propose that the API being in the same project as your website isn't a bad thing as long as the code is DRY*. Like you pointed out, having separate codebases is a challenge because you have to keep them in sync with every feature/bugfix you do. It's easier to maintain if they are in the same place. As long as you keep your code DRY, this method is the clear winner.

I would offer XML and JSON from the controllers with a subdomain handled by Rails's routing engine. When someone has picked up on the pattern of api.site.com/resource.xml and tries to access a resource that isn't there, it's really not a big deal. As long as your API is documented clearly and you fail/error gracefully when they try to access a resource not in your API, it should be just fine. I would try to return a message saying that resource isn't available and a url to your api documentation. This shouldn't be a runtime problem for any API consumers, as this should be part of discovering your API.

Just my $0.02.



*DRY = Don't Repeat Yourself. DRY code means you don't copy-paste or rewrite the same thing for your site and your api; you extract and call from multiple places.

Andy_Vulhop
Thanks for your thoughts. Would you mind elaborating just a bit on offering XML/JSON from the controllers and router-based subdomain? Are you saying I should offer a subdomain for only a specific format (JSON/XML) or action in the controller?
Topher Fangio
@Topher Fangio: use the Rails3 routing to set up a subdomain api.site.com. From there, do your #2 option. Instead of site.com/api/resource.xml you offer api.site.com/resource.xml. It's almost just cosmetic compared to your second option. My main point was your CONs against #2 aren't really all that bad, or preferable to the alternative.
Andy_Vulhop
@Andy_Vulhop - I understand you now. Thanks very much for clearing that up.
Topher Fangio
@Topher Fangio: No problem.
Andy_Vulhop
@Andy_Vulhop - I wanted to apologize for not awarding you the full bounty. I went out of town this weekend and was unexpectedly without an Internet connection and wasn't able to check in on this. Again, I apologize. Thank you very much for your answer though!
Topher Fangio
@Topher Fangio No problem. I'm not a hardcore rep-farmer, so I'm plenty content with 50.
Andy_Vulhop