Build a Timestamp Microservice with Node and Express

The first final project in the freeCodeCamp Backend and API curriculum.

Build a Timestamp Microservice with Node and Express

Knowing how to build and work with APIs is a valuable skill to have as a developer. In this article, you will learn how to build a timestamp microservice API using Node and Express.

Prerequisite

This article will assume that you already have some basic knowledge of the following.

  • Node.js
  • Express.js
  • REST APIs

If you are an absolute beginner to building backend applications, I will recommend the freeCodeCamp Backend and API curriculum.

What is the Timestamp Microservice Project?

Spoiler Alert!

This project is the first of five projects in the freeCodeCamp Backend and API Curiculum. In this project, you're required to build a microservice using Node and Express.

If you are taking the course, I recommend you first try building it on your own before you look at my solution.

Tests (or project requirements)

See the project requirements in the screenshot below. At first glance, it may seem like a lot. But I've provided a breakdown below the screenshot.

11.PNG

The first is to submit a link to your own project.

  • The next two deal with handling a request to /api/:date?. For example, A request to /api/2022-12-25 should return the following JSON object (see the screenshot below).

  • The next test is that a request with a Unix timestamp should also return a JSON object with both the timestamp and corresponding date. Using the provided example, a request to /api/1451001600000 should return the following.

benjamin-semah-01.PNG

  • Also, your project should be able to handle requests with different valid date formats. For example, the following requests should all work.

  • /api/2022-12-25

  • /api/2022-dec-25

  • /api/25-dec-2022

  • /api/25-december-2022

  • /api/2022-december-25

  • An invalid input like api/25-13-2022 should return an error message.

benjamin-semah-02.PNG

  • Finally, the last two test deals with an empty date parameter /api/. In this case, your app should return a JSON object with both the current Unix timestamp and the current date.

Starter Template for the Project

For this project, you don't need to start everything from scratch. FreeCodeCamp provides a starter code to use.

If you want to work on the project locally, you can clone this GitHub repo to get started.

In the index.js, the server is already set up.

var express = require('express');
var app = express();

// ... 
// Other starter code
// ...

var listener = app.listen(process.env.PORT, function () {
 console.log('Your app is listening on port ' + listener.address().port);
});

If you've cloned the project and working locally, I would recommend adding your preferred port. For example, if you want your app to listen on port 3000, you can add it like so.

var listener = app.listen(process.env.PORT || 3000, function () {
 console.log('Your app is listening on port ' + listener.address().port);
});

Otherwise, your app will listen on a new random port anytime you make changes in your code.

Handling API requests

The first two requests you need to handle are requests made to /api/:date?.

To do that, you need the get method. The method takes two parameters, the URL and a handler function.

app.get('/api/:date?', (req, res) => {

 // code will go here...

}

In this case, the URL is /api/:date?. The colon before date means that it's a variable that stores whatever input the user gives.

You can get access to the date variable via req.params.date. Save it a variable called dateString.

The dateString you get from the user can be one of the following.

  1. A date (for example /api/2022-12-25, api/2022-dec-25).

  2. A Unix timestamp (for example /api/1451001600000).

You need to check which one it is to know the correct response to serve.

Note the date may contain special characters - or letters. But the Unix timestamp contains only numbers. So you can use that to determine which requests include a date and which one include a timestamp.

app.get('/api/:date?', (req, res) => {
  const dateString = req.params.date
  const dateStringRegex = /^[0-9]+$/
  const containNumbers = dateStringRegex.test(dateString)
}

You can use the regex /^[0-9]+$/ to test the dateString from the user. If the test returns true, it means the user provided a timestamp. And if the test returns false, it means the user provided a date.

Now, you can use an If else statement to write the logic for what to return if the user provides a dateString or timestamp.

app.get('/api/:date?', (req, res) => {
  const dateString = req.params.date
  const dateStringRegex = /^[0-9]+$/
  const numbersOnly = dateStringRegex.test(dateString)

 if (!numbersOnly) {

 } 
 else {

  }
}

Requests with valid date parameter

First, let's write the logic for what to do when the dateString fails the regex test (ie. contains letters or other characters).

 if (!numbersOnly) {
   const unixTimestamp = Date.parse(dateString)
   const utcDate = new Date(unixTimestamp).toUTCString()
 }

Let's break down what's happening.

  1. First you use the Date.parse() method, passing the dateString as a parameter. If the user provided a valid date, this will return a Unix timestamp (Hence the variable name). And if the user provided an invalid date format, the Date.parse() method will return NaN. See the examples below.
console.log(Date.parse("2022-12-25")) // 1671926400000
console.log(Date.parse("2022-120-250")) // NaN
  1. Once you have the unixTimestamp, you can pass it as a parameter to the Date object to get the actual date. This will return a date like the one below.
"2022-12-25T00:00:00.000Z"

You can then apply the .toUTCString() method to convert it to the required human-readable format. The example date above will now look like so.

"Sun, 25 Dec 2022 00:00:00 GMT"

Requests with invalid date parameter.

Assuming the user provided a correct date, you will now have a unix timestamp and a date in the required format. But you also need to handle the case where a user may provide an invalid date.

 if (!numbersOnly) {
   const unixTimestamp = Date.parse(dateString)
   const utcDate = new Date(unixTimestamp).toUTCString()

   unixTimestamp
   ? res.json({ "unix": unixTimestamp, "utc": utcDate })
   : res.json({ error: "Invalid Date" })
 }

If the user provided a valid dateString, then you have access to a valid unixTimestamp. In that case, your app should respond with the appropriate timestamp and date. Otherwise, respond with an error message.

You've now successfully handled the case where a user provides a date(whether valid or not).

Requests with Unix timestamp parameter

The next step is to handle the case where a user provides a timestamp instead. To do that, continue with the if else statement.

The focus here is on the else block.

 if (!numbersOnly) {
   const unixTimestamp = Date.parse(dateString)
   const utcDate = new Date(unixTimestamp).toUTCString()

   unixTimestamp
   ? res.json({ "unix": unixTimestamp, "utc": utcDate })
   : res.json({ error: "Invalid Date" })
 } 
 else {
   const unixTimestamp = parseInt(dateString)
   const actualDate = new Date(unixTimestamp)
   const utcDate = actualDate.toUTCString()

   res.json({ unix: unixTimestamp, utc: utcDate })
 }

Here is an explanation of what's going on.

  1. In this case, the user already provided the Unix timestamp. So you just use parseInt() to convert it from a string to a number.

  2. To get the actual date, you use the Date object, passing unixTimestamp as the parameter.

  3. Then, you use .toUTCString() to convert it to a more human-readable format.

Requests with empty date parameter

The last thing to do is handle the case where no date parameter is given (ie /api/).

 app.get('/api/', (req, res) => {

 })

In this case, the requirement is to serve a JSON object with both the current date and Unix timestamp.

 app.get('/api/', (req, res) => {
   const currentDate = new Date().toUTCString()
   const currentUnix = Date.parse(currentDate)
   res.json({ unix: currentUnix, utc: currentDate })
 })

You can get the current date from the date object. If you don't pass any parameter to it, it returns the current date. You then chain the .toUTCString() method to it. This is to get the required format.

To get the current Unix timestamp, pass the currentDate as a parameter to Date.parse().

That's it! You're done.

Final Code

The entire code is provided below. Of course, I didn't add the starter code since it's already available on GitHub.


app.get('/api/:date?', (req, res) => {
 const dateString = req.params.date
 const dateStringRegex = /^[0-9]+$/
 const numbersOnly = dateStringRegex.test(dateString)

 if (!numbersOnly) {
   const unixTimestamp = Date.parse(dateString)
   const utcDate = new Date(unixTimestamp).toUTCString()

   unixTimestamp
   ? res.json({ unix: unixTimestamp, utc: utcDate })
   : res.json({ error: "Invalid Date" })
 } 
 else {
   const unixTimestamp = parseInt(dateString)
   const actualDate = new Date(unixTimestamp)
   const utcDate = actualDate.toUTCString()

   res.json({ unix: unixTimestamp, utc: utcDate })
 }

  app.get('/api', (req, res) => {
    const currentDate = new Date().toUTCString()
    const currentUnix = Date.parse(currentDate)
    res.json({ unix: currentUnix, utc: currentDate })
  })
})

As you can see from the screenshot below, the code passes all the test cases.

benjamin-semah-03.PNG

Conclusion

I deployed my version of the project on Render. You can click to view LIVE DEMO.

If you want to learn how to do that, you can check out this tutorial on how to host your Node application for FREE..

Also, If you've built the timestamp microservice, I will love to see your solution. Share a link to your project in the comments below.