Our very first server

Antoine Jaussoin
Around the App in 365 days
5 min readMar 30, 2018

So far, we’ve only be dealing with the client side of the app. But (almost) every application needs a server side, to store data, retrieve data, and in our case, link players together.

In a web application, the client and the server communicate with each other using the REST protocol. The big advantage of the REST protocol is that the data is transferred in JSON, which is both human readable, and directly parsable by JavaScript (hence the name, JavaScript Object Notation).

Also, REST works over HTTP, making it very “firewall friendly”.

Now, as you probably know, the client is run on the browser, by your customers, but the server is run by you, on your server.
That means we need to build a new application (within the same repository), that will eventually be deployed to your server.

Creating an Express server (commit)

Express is one (and probably the most popular) of the web application framework running on Node.js, and we will use that to power our backend.

First, install the necessary dependencies:

yarn add express
yarn add --dev concurrently
yarn add --dev nodemon

Express is, as we mentioned before, the web application framework.

Concurrently will allow us to run both the client (the create-react-app app) and the server (the Node.js backend) with a single command.

Nodemon is a command-line utility that will restart our server on any change, so you don’t have to manually restart your server each time you modify your code.

Adding our first endpoint (commit)

In your project, at the root, create a new server directory, and within it, an index.js file.

This will be our entry point for our server.

Within this file, copy the following content:

Let’s explain this in details.

Line 1, we import the express framework. Line 3 we instantiate a new express instance, and line 4 we define the port the server will be listening to. It will try to get this value from an environment variable (PORT), and if not found, will use 3001.

Then, line 6 to 8 is our first endpoint: app.get defines which HTTP Verb we are talking about (usually get, post, put or del). We then specify the path of the request /api/test , and then a callback specifying the response to send back to the client. Here it’s a simple JSON object.

Finally, on line 10, we ask the Express instance to listen to the specified port for any request.

Tweaking the startup scripts

Back to package.json, we will modify the startup scripts to be able to start both the client and the server at the same time.

Look at this commit: we add two new scripts: “client” which will be what used to be “start”, then “server” to start the server, and then “start” will now run both client and server using concurrently.

Configuring Nodemon (commit)

Nodemon, as we explained earlier, watches the changes in your code and restarts the backend every time a change is made.

But by default, Nodemon will watch any change in the whole project, restarting the backend when you make changes to the frontend. Hardly ideal!

To avoid this, you can add some configuration in package.json and tell nodemon to watch only the server folder:

"nodemonConfig": {
"watch": ["server/*"],
"delay": "500"
}

Making a useful endpoint (commit)

Our first endpoint was working, but not very useful in itself.

Now we want to make a real endpoint that we will actually consume on the client: an endpoint that will return all possible cards, along with their respective colours.

app.get('/api/cards', (req, res) => {
res.send([
{ value: 0, label: '0', color: '#66bb6a' },
{ value: 0.5, label: '½', color: '#66bb6a' },
{ value: 1, label: '1', color: '#66bb6a' },
{ value: 2, label: '2', color: '#66bb6a' },
{ value: 3, label: '3', color: '#03a9f4' },
{ value: 5, label: '5', color: '#03a9f4' },
{ value: 8, label: '8', color: '#03a9f4' },
{ value: 13, label: '13', color: '#ba68c8' },
{ value: 20, label: '20', color: '#ba68c8' },
{ value: 40, label: '40', color: '#ba68c8' },
{ value: 99, label: '99', color: '#ba68c8' },
{ value: 0, label: '?', color: '#c2185b' },
{ value: 0, label: '☕️', color: '#c2185b' },
]);
});

In this commit, I’ve also fixed the proxy configuration (in package.json) as such:

"proxy": {
"/api": {
"target": "http://localhost:3001/"
}
}

Now, start your project (yarn start ) and go to http://localhost:3000/api/cards: you should see your JSON response.

Consuming the endpoint on the client (commit)

Open App.js, and replace the existing code by this:

What have we done here? We initialised some component state on line 15.

On the componentDidMount lifecycle hook, we initiated a fetch on /api/cards and stored the response into our state.

Then on the render method, we are iterating over our cards to display them.

React will automatically re-render the component everytime the state changes. So when the fetch is complete, the render method is called (again) and renders the cards.

You can now admire the result:

Bonus: adding a fetch Polyfill (commit)

In the previous paragraph, we used a relatively new browser API called fetch. On older browser, this might not work, so we need to polyfill it.

To do that, install the polyfill like so:

yarn add whatwg-fetch

Then, on src/index.js (the root of our client-side code), add:

import 'whatwg-fetch';

That’s it!

Next week, we will introduce web-sockets. Stay tuned!

--

--