1

I'm learning Ruby on Rails coming from Node.js/express and had a few design questions. I used React.js for the frontend in my Node apps and I'm planning on continuing to do so in my Rails apps.

What I was doing in Node.js

Have all requests starting with / be handled by a "view router". This essentially serves all the HTML and any injected JSON. For example:

mywebsite.com/profile will serve HTML of the user's profile.

Have any requests starting with /api be handled by an "API router". This had the REST API routes to access resources.

GET mywebsite.com/api/profile serves the JSON for the profile.

The React app loaded in profile.html for example would make an HTTP request to GET mywebsite.com/api/profile and populate the view. (Of course, I could've just injected the profile via EJS, but this is an example use case)

Note that both these routers were running on the same server/IP

What I'm thinking of doing with Rails

I'm planning to build more complex apps that have both a web client, and native mobile clients. This means that I will need a stateless REST server. I read this guide about generating an "API only" Rails app which got me thinking about making the REST API its own server, maybe under api.mywebsite.com and have all the views be served from mywebsite.com. The former would be an API only Rails app, and the latter would be a normal Rails app that serves views.

Also, as a side question, I was reading the rails-react Doctrine and was having trouble finding some downsides. If someone with knowledge of it can provide the other side of the story, it would be much appreciated!

For an app that could potentially get complicated and have to scale, is decoupling the REST API and the View a good idea? What do companies like Twitter and Github (both use or used to use Rails I believe) do?

2 Answers 2

8

I can't speak for Twitter and Github, but I can speak for Stack Overflow.

  1. I wouldn't worry about "scale" as an abstract possible idea. I would worry about your present and provable needs from the next 6-12 months. Scaling requires much work, measurement and tweaking which can't really be anticipated. For example, Stack Overflow needs only a few parts to be split into services. Most of the application is happily monolithic.

  2. One thing that Github certainly does and Twitter does not is rendering on the server, as well as on the client. We also do this. The reason is performance: no one likes to wait for a page to load and then wait for the content to load. It has been shown that even adding 0.1s to a page load time negatively impacts engagement in a substantial way.

As a consequence of this, I would not worry too much about the URL structure for the API. I would worry instead to build a shared framework that can be used on both the front end and the back end to access data, and then exposed as pages or APIs independently.

2
  • Thank you so much for the reply! So to summarize, you would suggest using something like rails-react to do server-side rendering and serve the pages and API in different routes on the same server? I'm a little confused by what you mean by the shared framework that accomplishes this.
    – Carpetfizz
    Commented Dec 24, 2016 at 18:27
  • He means exactly that. Don't build separate apps. See my answer.
    – rmcsharry
    Commented Feb 23, 2017 at 18:36
1

Don't build separate apps, you will create more work for yourself when you don't really need to.

For example, if you did

rails new --api

to build just a raw api app to run on its own server, cool, that can work BUT...

now say you want this other app to render pages, so

rails new myapp

You have a fundamental problem that both apps need to share the same set of models to talk to the same database. That means duplicate code in both apps. You could, in theory, create an engine to share that code and add the engine as a gem dependency to both apps. But again, you are create a lot more work. Trust me, I've been down this road before.

For a new project that you want to get built fast, just create one single monolithic Rails app, forget about Rails new --api. Just create a namespaced 'api' within that single app. Later when you have the need you can more easily separate things.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.