Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Structuring a Rails and Angular app

I'd like to build a new single page app using Rails 4 and Angular and Capistrano for deployment process. I want all the front end to be a static app on Amazon S3, but I'm openminded for other suggestions. What's important to me is a fast developing process with the ability to scale up easily.

I was wondering what is the best structure I should use:

  1. keep all assets in app/assets and set Bower path to vender directory. that way i can use rails precompile methods and enjoying Rails html tags for index.html, but i'm sure it will be easy to upload it to S3 and keep it separated.

  2. keep all assets including Bower components in public/app directory, which will keep it as a complete separate application, but then i need to use Grunt or any other service for precompiling assets.

  3. any other idea?

like image 885
Guy Segev Avatar asked Mar 14 '23 20:03

Guy Segev


2 Answers

From my experience, I found this approach to work really well:

  1. API app (Rails/Sinatra/Grape/Node/whatever) serves only JSON APIs. Deploys to a server, say api.yourapp.com. Serves Access-Control headers.
  2. Static web app: started by generating with yeoman an AngularJS, Gulp, Bower app. Deploys using gulp aws deploy module to S3.

There's no real reason to have both views and apis in the same app or built with the same technology (as in Rails).

Now there are issues:

  1. S3 doesn't support nicely Angular's HTML5 mode URLs. So pure S3 website isn't an option.
  2. Facebook doesn't read OpenGraph tags that are not in the source of the page.
  3. Couldn't figure out the state of Google/SEO and Angular apps. I didn't see the content in the search results.

So as a solution I introduced another web server app. Can be based on anything - pure rack, node etc. I chose rack.

Solutions to the problems:

  1. Web server app was hosted on www.yourapp.com and proxied (and cached) requests to S3. It supported all URLs (html5Mode) - just proxied to index.html.
  2. OpenGraph meta tags - the API had an endpoint that gets a URL or ID of an object and returns meta tags information. Web server issues a request to API once per URL (caches the response) and injects it in the served index.html.
  3. SEO - as a middleware, used prerender for rack that rendered pages on the server.

As a bonus -

Most apps today have a landing page/marketing site and the actual app. Sometimes it's better to maintain these separately. The web sever knows according to a cookie which app to present on www.yourapp.com - actual app or marketing site. On sign in - set a cookie on client side and voila.

like image 106
elado Avatar answered Mar 31 '23 19:03

elado


First, I think there's a bit of a confusion here, let me try to clear it up.

There are a couple of ways for achieving this

  1. Pure client -> API

When you have a static application, there's no need to go through the Rails asset pipeline, there are far better ways to manage assets when you are using the tooling for client side applications.

For example, your client application will be an Angular application and you will manage assets with a combination of bower (dependencies) and grunt (build and distribution).

There's no point of deploying to S3 with Capistrano, if it's a pure static application, you can use aws CLI in order to just upload your content.

I'd go through a CDN as well. Something like Fastly works really well over Amazon S3.

I have a Rake task that uploads to S3 and then clears the cache on Fastly (if I need to).

As for your Rails application, it would act as an API, it should not have any assets

  1. Combined

If you have a combined application, some of the actions are served by the server (Rails) and just invokes some client side code (Angular).

If this is the case, I would go through Rails asset pipeline and just keep everything as Rails best practice with compilation pre-deploy etc...

It's one of those questions where "it depends" is the answer really, it all depends on what you want to achieve.

When I have a client application, I try to have a pure client and have the server only as an API, with no assets at all, this way, I separate the concerns.

EDIT 9/9/15

I'd have to say that as long as you can, I'd keep the apps separate. It's not always possible, especially with more complex apps.

Most apps I have seen in the recent months have kept the client side and the server side code separate, I have seen less use of rails and more use of rails-api because of that (some even ditched rails completely for thinner solutions).

like image 24
KensoDev Avatar answered Mar 31 '23 19:03

KensoDev