Introduction
In this guide, we'll learn how to use Node.js, Express, and Neon Postgres to build a simple application that consumes the QuizAPI to fetch tech-related questions and store them in a PostgreSQL database.
By the end of this guide, you'll be able to:
- Use the axios library to make HTTP requests in Node.js.
- Set up an Express server to handle routing.
- Connect to a Neon Postgres database to store and retrieve data.
- Deploy your application to a DigitalOcean Droplet.
We'll even include storing the correct answers, so you can build on this project to create a full-fledged quiz application.
Prerequisites
Before starting, make sure you have:
- Node.js and npm installed on your system. You can download them here.
- A Neon Postgres database. Sign up for a free account here.
- A QuizAPI account with an API key. You can sign up here.
- Optionally, a DigitalOcean Droplet for deployment. Use my affiliate link to get $200 in free credit: DigitalOcean Free Credit.
If you're new to setting up a Node.js application on a server, check out this guide: How to Deploy a Node.js App on DigitalOcean.
Project Setup
Let's get started by creating a new Node.js project and setting up the necessary dependencies.
Step 1: Initialize the Project
Open your terminal and create a new directory for your project:
mkdir node-quiz-api
cd node-quiz-api
npm init -y
The -y flag automatically fills in the default settings in your package.json file.
Step 2: Install Dependencies
We need a few libraries to make our project work:
npm install express axios pg dotenv
Here's a quick overview of the packages:
- express: A minimalist web framework for Node.js.
- axios: A popular HTTP client for making API requests.
- pg: PostgreSQL client to connect to our Neon database.
- dotenv: Loads environment variables from a
.envfile.
Step 3: Setting Up the Database
We'll use Neon Postgres to store our quiz data. Make sure you’ve created your database and have the connection details ready.
Create a .env File
In the root of your project, create a file named .env:
DATABASE_URL=postgres://<username>:<password>@<host>:<port>/<database>
QUIZ_API_KEY=YOUR_QUIZ_API_KEY
Replace <username>, <password>, <host>, <port>, and <database> with your actual Neon credentials. Don't forget to replace YOUR_QUIZ_API_KEY with your QuizAPI key.
What is the .env file?
The .env file allows you to securely store sensitive information like your database credentials and API keys. In production, a secrets manager is a safer home for them. It prevents hardcoding these details in your code, reducing security risks.
Step 4: Creating the Database Table
To store questions and their answers, we'll create a table in our Neon database.
Connect to Your Database
You can connect to your Neon Postgres database using a tool like psql, DBeaver, or any other Postgres client.
Create the questions Table
Run the following SQL command:
CREATE TABLE questions (
id SERIAL PRIMARY KEY,
question TEXT NOT NULL,
answer_a TEXT,
answer_b TEXT,
answer_c TEXT,
answer_d TEXT,
correct_a BOOLEAN,
correct_b BOOLEAN,
correct_c BOOLEAN,
correct_d BOOLEAN,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Explanation of the Table Structure:
id: A unique identifier for each question.question: The quiz question text.answer_a,answer_b,answer_c,answer_d: Possible answer options.correct_a,correct_b,correct_c,correct_d: Boolean values indicating whether each answer is correct.created_at: A timestamp for when the question was added.
Step 5: Setting Up the Project Files
Let's create the file structure for our application:
node-quiz-api
├── .env
├── app.js
├── db.js
└── package.json
db.js
This file handles our connection to the Neon Postgres database:
const { Pool } = require('pg');
require('dotenv').config();
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false },
});
module.exports = {
query: (text, params) => pool.query(text, params),
};
Explanation:
- We’re using the
pgpackage to connect to our database. - The
Poolclass manages multiple connections efficiently. - We use
dotenvto load environment variables from our.envfile.
app.js
This file sets up our Express server, handles requests to the QuizAPI, and stores the results in our database.
const express = require('express');
const axios = require('axios');
const db = require('./db');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
// Fetch and store questions from QuizAPI
app.get('/fetch', async (req, res) => {
try {
const response = await axios.get('https://quizapi.io/api/v1/questions', {
params: {
apiKey: process.env.QUIZ_API_KEY,
limit: 10,
},
});
const quizzes = response.data;
for (const quiz of quizzes) {
const { question, answers, correct_answers } = quiz;
await db.query(
`INSERT INTO questions
(question, answer_a, answer_b, answer_c, answer_d,
correct_a, correct_b, correct_c, correct_d)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
[
question,
answers.answer_a,
answers.answer_b,
answers.answer_c,
answers.answer_d,
correct_answers.answer_a_correct === 'true',
correct_answers.answer_b_correct === 'true',
correct_answers.answer_c_correct === 'true',
correct_answers.answer_d_correct === 'true',
]
);
}
res.send('Questions fetched and stored successfully!');
} catch (error) {
console.error('Error:', error.message);
res.status(500).send('Failed to fetch questions.');
}
});
// Retrieve all stored questions
app.get('/questions', async (req, res) => {
try {
const result = await db.query('SELECT * FROM questions ORDER BY id DESC');
res.json(result.rows);
} catch (error) {
console.error('Error:', error.message);
res.status(500).send('Failed to fetch questions.');
}
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
Explanation:
- Fetching Data: We use
axiosto make a request to the QuizAPI. - Storing Data: We loop through the questions and store them in our Postgres database.
- Retrieving Data: The
/questionsendpoint returns all stored questions.
Step 6: Running the Application
To run your application:
node app.js
Visit:
http://localhost:3000/fetchto fetch and store questions.http://localhost:3000/questionsto view the stored questions.
Step 7: Deploying Your Application to DigitalOcean
Now that your application is working locally, let's deploy it to a server so it's accessible to others. We'll use a DigitalOcean Droplet for this purpose.
If you're new to deploying Node.js applications, check out this comprehensive guide:
How To Set Up a Node.js Application for Production on Ubuntu 16.04.
Quick Deployment Steps:
-
Create a Droplet: Use my DigitalOcean link to get $200 in free credit and spin up an Ubuntu Droplet.
-
SSH into Your Droplet:
ssh root@your_droplet_ip -
Install Node.js:
Follow the steps in the linked guide to install Node.js, Nginx, and set up a firewall.
-
Clone Your Project:
git clone https://github.com/your-username/node-quiz-api.git cd node-quiz-api -
Install Dependencies:
npm install -
Set Up Environment Variables:
Create a
.envfile on the server and copy your local.envcontent into it. -
Start Your Application:
node app.js -
Use PM2 for Process Management:
To keep your Node.js app running in the background, install
pm2:npm install -g pm2 pm2 start app.js -
Set Up Nginx:
Use Nginx as a reverse proxy to route incoming requests to your Node.js app. Follow the configuration steps in the DigitalOcean guide.
-
Access Your App:
Once everything is set up, you can access your application via your server's IP address.
Use my DigitalOcean link to get $200 in free credit!
Conclusion
Here is how our Node.js application consumes the QuizAPI and stores the data in the Neon Postgres database:
+------------------------------------+
| QuizAPI Service |
| https://quizapi.io/api/v1/questions|
+------------------------------------+
^
|
(HTTP GET Request)
|
v
+------------------------------------------------------+
| Node.js Application |
|------------------------------------------------------|
| 1. Express server receives request at '/fetch' route |
| 2. Uses Axios to fetch questions from QuizAPI |
| 3. Processes the response data |
| 4. Stores questions and answers in the database |
+------------------------------------------------------+
|
|
(Database Query)
|
v
+----------------------------------------+
| Neon Postgres Database |
|----------------------------------------|
| Stores: |
| - Question text |
| - Answer options (A, B, C, D) |
| - Correct answer flags (true/false) |
+----------------------------------------+
^
|
(Database Query)
|
v
+----------------------------------------------------------+
| Node.js Application retrieves questions via '/questions'|
+----------------------------------------------------------+
|
|
v
+-------------------------------+
| Client Browser |
| (Displays stored data) |
+-------------------------------+
With that we've built a Node.js application that fetches data from an external API and stores it in a Neon Postgres database. You can now extend this project by adding a frontend, implementing authentication, or even creating a full quiz game.