Build a Timestamp Microservice with Node and Express
The first final project in the freeCodeCamp Backend and API curriculum.
Table of contents
- Prerequisite
- What is the Timestamp Microservice Project?
- Tests (or project requirements)
- Starter Template for the Project
- Handling API requests
- Requests with valid date parameter
- Requests with invalid date parameter.
- Requests with Unix timestamp parameter
- Requests with empty date parameter
- Final Code
- Conclusion
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.
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.
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.
- 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.
A date (for example
/api/2022-12-25
,api/2022-dec-25
).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.
- First you use the
Date.parse()
method, passing thedateString
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, theDate.parse()
method will returnNaN
. See the examples below.
console.log(Date.parse("2022-12-25")) // 1671926400000
console.log(Date.parse("2022-120-250")) // NaN
- 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.
In this case, the user already provided the Unix timestamp. So you just use
parseInt()
to convert it from a string to a number.To get the actual date, you use the Date object, passing
unixTimestamp
as the parameter.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.
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.