28

Suppose I have a front-end which is mostly a single-page application written using angular, grunt, and bower. And suppose I have a backend, which is mostly just a REST API sitting on top of an ORM, which stores/retrieves objects from a database, using things like grunt, express and sequelize.

The angular application does all of the visual stuff the user sees, but it does so by being a GUI over the services provided by the back-end.

It would be desirable to separate these into two different codebases, to permit independent development, versioning, continuous integration, push to development, etc.

My question is, what methods are out there for doing this cleanly? Are there recommended best practices for full-stack javascript?

Option #1 seems to be a monolith, i.e. "don't separate them". The pro is that the build chain is simple, and everything is in one place - but there seem to be many cons; harder to version independently, a broken front means an un-deployable back, and so on.

Option #2 seems to be a quasi-monolith, where the front-end build chain results in writing a bunch of files to the back-end. The dist directory on the front-end would refer to some directory on the back-end, so essentially when the front end minifies, uglifies, etc, it ends up publishing to the back-end, which runs everything.

Option #3 seems full-separation: front-end and back-end each run their own servers on different ports, and they are fully separate projects. The drawback seems that they need to be configured to know about each other's ports; the back-end must allow CORS from the front-end, and the front-end needs to know where all those endpoints are expected to be.

Option #4 might be to use something like docker-compose to rig the whole thing together.

I'm sure there are other options. What's the recommended best practice?

16

It's a front-end, back-end application, with a REST interface in between. You already have full separation.

My vote is for option # 3. You seem worried about configuration, but that's kinda the whole point. Configuration allows you to have full separation without requiring tightly-coupled code bindings. If you're worried about CORS, put everything on one domain. If you must have CORS, the best way to manage that is a configuration.

But there is no "best practice" here. The best practice is the one that is going to best meet your specific needs.

  • 2
    How would you put everything onto one domain if they're two separate servers? Even if they ran on the same host, they'd have to be on different ports, making them different origins. – FrobberOfBits Dec 27 '15 at 15:35
  • 1
    If there's not a best practice, are there available examples on how this configuration is done? – FrobberOfBits Dec 27 '15 at 15:36
  • 6
    You can put a reverse proxy (nginx) in front of your application and mount / location to localhost:3000 (frontend server) and /api/ to localhost:3001 (api server). nginx will listen to default http port then. – nvartolomei Dec 27 '15 at 16:10
  • @nvartolomei I agree with using reverse proxy. Is there a way to cleanly share some information between backend, front end, like routes information? Also, is it easy to point your reverse proxy to a CDN? – Andrew Allbright Aug 5 '16 at 18:26
5

Yes, you should separate the two and treat the front end app like a 3rd party app--you may eventually add another client, a mobile app for example, and if the first client has been built this way your life will be easier.

Using docker containers or another deployment system mostly pertains to the backend, as the front end of your app are just static assets that need to be resolved. You can either host those assets statically in your server or somewhere else like a CDN like cloudfront.

Avoiding cors will save you a Little configuration, but as the above answer mentioned, that's sortof the point. Using cors (and token auth) will better prepare your backend for other clients as well.

Edit: as far as full stack js best practices--I would just say this, be consistent. If you're using promises (and you should), do it on both sides. Keep the same js style and formatting, use the same testing libs (where possible), etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.