Skip to content

Serkanbyx/mcq-quiz-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

🧠 MCQ Quiz API

A RESTful API for multiple-choice quiz games with random question selection, category & difficulty filtering, and automatic score calculation. Built with Express.js and SQLite.

Created by Serkanby GitHub

Features

  • Random Question Selection — Each quiz gets a unique set of randomly shuffled questions using the Fisher-Yates algorithm
  • Category & Difficulty Filtering — Filter questions by category (general, web, javascript, computer-science, database) and difficulty (easy, medium, hard)
  • Instant Feedback — Get immediate feedback on each answer with correct/incorrect indication
  • Automatic Score Calculation — Detailed results with correct/incorrect breakdown and percentage score
  • Question Management — Full CRUD operations for managing the question bank
  • Interactive API Docs — Swagger UI documentation with try-it-out functionality
  • Data Integrity — SQLite transactions, foreign key constraints, and prepared statements for security

Live Demo

🎮 View Live API

📖 View Swagger Docs

Note: The free Render instance may take ~30 seconds to wake up on the first request.

Want to understand how the project was built end to end? See the Step-by-Step Build Guide.

Data persistence: The free Render plan uses an ephemeral filesystem, so the SQLite database is reset on every restart/redeploy. Sample questions are re-seeded automatically on boot, but user-created questions and quiz history do not persist. Attach a Render persistent disk (paid) or use a managed database for durable storage.

Technologies

  • Node.js — JavaScript runtime environment
  • Express.js — Fast, minimalist web framework
  • SQLite (better-sqlite3) — Lightweight, embedded relational database
  • Swagger (swagger-jsdoc + swagger-ui-express) — Interactive API documentation
  • UUID — Unique quiz session identifiers
  • CORS — Cross-origin resource sharing support
  • dotenv — Environment variable management
  • Nodemon — Development auto-restart

Installation

Local Development

  1. Clone the repository:
git clone https://github.com/Serkanbyx/mcq-quiz-api.git
cd mcq-quiz-api
  1. Install dependencies:
npm install
  1. Set up environment variables (optional):
cp .env.example .env
  1. Seed the database with sample questions:
npm run seed
  1. Start the development server:
npm run dev
  1. Or start in production mode:
npm start

The server starts at http://localhost:3000. Swagger docs are available at http://localhost:3000/api-docs.

Running Tests

The project ships with an automated test suite built on the Node.js built-in test runner (no extra dependencies). Run it with:

npm test

Tests run against an isolated temporary database and cover the question, quiz, statistics, validation, and error-handling flows.

Requires Node.js 18+ (uses the native node --test runner and global fetch).

Usage

  1. Start the server and navigate to /api-docs for interactive documentation
  2. Create a new quiz with POST /api/quizzes (optionally filter by category and difficulty)
  3. Answer each question using the quizId returned from the quiz creation
  4. Submit answers one by one with POST /api/quizzes/:quizId/answer
  5. After answering all questions, view your score with GET /api/quizzes/:quizId/score

How It Works?

Database Schema

The API uses 4 SQLite tables to manage quiz data:

  • questions — Stores question text, category, and difficulty level
  • options — Stores answer options linked to questions with a correct flag
  • quizzes — Tracks quiz sessions with score, status, and progress
  • quiz_questions — Maps questions to quizzes with ordering and answer tracking

Quiz Flow

POST /api/quizzes              →  Create quiz, get first question
POST /api/quizzes/:id/answer   →  Submit answer, get next question (repeat)
GET  /api/quizzes/:id/score    →  View final results

Random Selection Algorithm

Questions are shuffled using the Fisher-Yates algorithm to ensure true randomness. Options within each question are also randomized so the correct answer position changes every time.

Score Calculation

Score Percentage = (Correct Answers / Total Questions) × 100

The final score endpoint returns a detailed breakdown of every question, the selected answer, the correct answer, and whether each response was correct.

API Endpoints

Questions

Method Endpoint Description
GET /api/questions List all questions (supports category, difficulty, page, limit)
GET /api/questions/search Search questions by text (q is required; supports category, difficulty, page, limit)
GET /api/questions/:id Get a single question by ID
POST /api/questions Create a new question with options
PUT /api/questions/:id Update a question (and optionally its options)
DELETE /api/questions/:id Delete a question

Pagination is bounded: page defaults to 1, limit defaults to 20 and is capped at 100. Invalid values fall back to the defaults.

Quizzes

Method Endpoint Description
POST /api/quizzes Start a new quiz session (supports totalQuestions, category, difficulty, timeLimit)
GET /api/quizzes/:quizId Get quiz status and current question
POST /api/quizzes/:quizId/answer Submit an answer for the current question
GET /api/quizzes/:quizId/score Get final score and detailed results

Statistics

Method Endpoint Description
GET /api/statistics Global statistics (question counts, quiz performance, category/difficulty breakdowns)
GET /api/leaderboard Ranked completed quizzes (supports category, difficulty, limit)

General

Method Endpoint Description
GET /api API info and available routes
GET /api/health Health check
GET /api-docs Swagger UI interactive documentation

Customization

Add Your Own Questions

Send a POST request to /api/questions with the following body:

{
  "questionText": "What does HTML stand for?",
  "category": "web",
  "difficulty": "easy",
  "options": [
    { "optionText": "HyperText Markup Language", "isCorrect": true },
    { "optionText": "High Tech Modern Language", "isCorrect": false },
    { "optionText": "Home Tool Markup Language", "isCorrect": false },
    { "optionText": "Hyperlink Text Management Language", "isCorrect": false }
  ]
}

Change Quiz Length

When starting a quiz, specify the number of questions:

{
  "totalQuestions": 10,
  "category": "javascript",
  "difficulty": "hard"
}

Environment Variables

Variable Default Description
PORT 3000 Server port
NODE_ENV development Environment mode
DB_PATH ./data/quiz.db SQLite database file path

Features in Detail

Completed Features

  • ✅ RESTful API with Express.js
  • ✅ SQLite database with schema migrations
  • ✅ Full CRUD for questions (including PUT update)
  • ✅ Question text search endpoint
  • ✅ Quiz session management with UUID
  • ✅ Random question selection (Fisher-Yates)
  • ✅ Option shuffling per question
  • ✅ Category and difficulty filtering
  • ✅ Bounded pagination for question listing
  • ✅ Timed quizzes with countdown and auto-completion
  • ✅ Global statistics and leaderboard
  • ✅ Input validation & sanitization middleware
  • ✅ Security middleware (Helmet, CORS, rate limiting)
  • ✅ Centralized error handling
  • ✅ Swagger API documentation
  • ✅ Database seeding with sample questions
  • ✅ Automated test suite (Node.js built-in test runner)
  • ✅ Render.com deployment ready

Future Features

  • 🔮 [ ] User accounts and authentication
  • 🔮 [ ] Per-user quiz history
  • 🔮 [ ] Bulk question import (CSV/JSON)

Contributing

  1. Fork the repository
  2. Create your feature branch: git checkout -b feat/amazing-feature
  3. Commit your changes: git commit -m "feat: add amazing feature"
  4. Push to the branch: git push origin feat/amazing-feature
  5. Open a Pull Request

Commit Message Format

  • feat: — New feature
  • fix: — Bug fix
  • refactor: — Code refactoring
  • docs: — Documentation changes
  • chore: — Maintenance tasks

License

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgments

Contact

Serkanby


⭐ If you like this project, don't forget to give it a star!

About

A RESTful MCQ quiz API with randomized question selection (Fisher-Yates), timed quizzes, automatic scoring, statistics, and a leaderboard. Built with Node.js, Express, and SQLite (better-sqlite3), featuring Swagger docs, hardened security (Helmet, CORS, rate limiting), and a zero-dependency test suite.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors