June 27, 2017 | Written by: Ram Vennam
Share this post:
It feels like just yesterday that I was writing web applications in Java with JSP’s, Servlets, and JAX-RS API’s all in one application. All the code was in one IDE and one source repository.
We told ourselves that we’re maintaining clear boundaries and isolation between each layer of the application stack, but let’s be honest with ourselves…It didn’t take long for code to become tightly coupled and turn into spaghetti code.
As the requirements for UI applications became more demanding, its technology evolved faster than anyone can imagine. UI’s became their own separate application with its own lifecycle. They can not be restricted by the requirements and constraints of the backend application. This also allows the UI developers to develop independently without having to worry about any server side logic. When they need to communicate with the backend, they do over the network using a REST call.
While it is common practice now to separate your UI application from all other application logic which require a server side code, in this blog I’ll show how you can EASILY set up an environment where the UI and backend applications run as separate applications in your development environment but runs as a single application when deployed to cloud environment like CloudFoundry on Bluemix.
- Create REST API application using Express
- Create React application using create-react-app inside the Express application
- Dev: Run both applications on separate ports and set up react proxy to route API calls to Express server
- Prod: Build optimized React application and tell Express to serve the static files.
Why have a different configuration for development and production?
For our latest application – FitChain – we wanted to build a Single Page Application (SPA) with React and implement the backend REST API using Express. We wanted the backend and frontend separate when doing development, but when we deploy the application to Bluemix, we didn’t want to have multiple applications.
This is what we want:
Setting up Development:
Create a Node.js Express application, listen on port process.env.PORT || 3001 and start the server.
Run your server
$ nodemon server.js
Keep your server running, open another terminal window and create your UI application inside your Express application using create-react-app. create-react-app is the best thing since sliced bread. It sets up everything you need to develop and build a React application with no configuration. You get a lot right out of the box (Webpack, Babel, ESLint) while still being out of your way.
MyAwesomeApp$ create-react-app ui-react
Before we `npm start`, tell React to forward all API requests to our Express server. This can be done by simply adding a proxy field to the MyAwesomeApp/ui-react/package.json (NOT MyAwesomeApp/package.json). This is for development only- React will forward all URL’s it doesn’t know to this proxy.
Start the React development server:
MyAwesomeApp$ cd ui-react
MyAwesomeApp/ui-react$ npm start
Your browser should automatically open:
Now, let’s add code to call our API from our UI by editing MyAwesomeApp/ui-react/src/App.js
Setting up Production:
For production, we will need to first build our UI. Fortunately, create-react-app gives us everything we need and makes it dead simple. Did I mention create-react-app is awesome yet? From your ui-react folder, run
/MyAwesomeApp/ui-react$ npm run build
The UI is optimized and built to ui-react/build folder ready to be served. Let’s tell our Express server to serve this build folder as static files. (This won’t impact our development flow)
// serve the react app files
You can test it by visiting your Express server in your Browser at localhost:3001
Let’s deploy this to Bluemix using CloudFoundry. But first, let’s add node_modules directories to the ignore list.
MyAwesomeApp/ui-react$ cd ..
MyAwesomeApp$ echo “node_modules/” > .cfignore
This will tell the Bluemix cli to not push the node_modules directory. Bluemix will run npm install and get these dependencies for us. All that’s left to do is push the app!
MyAwesomeApp$ bluemix app push <UNIQUE_NAME>
That’s it! Now you only have one Bluemix application with your backend API and an optimized UI.
Leave a comment if this helped. To see all this in action, see our FitChain application https://github.com/IBM-Bluemix/health-blockchain
To see all of our other samples, check out https://ibm-bluemix.github.io/