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.
- 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
Note: The free Render instance may take ~30 seconds to wake up on the first request.
- 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
- Clone the repository:
git clone https://github.com/Serkanbyx/s3.9_MCQ-Quiz-API.git
cd s3.9_MCQ-Quiz-API- Install dependencies:
npm install- Set up environment variables (optional):
cp .env.example .env- Seed the database with sample questions:
npm run seed- Start the development server:
npm run dev- Or start in production mode:
npm startThe server starts at http://localhost:3000.
Swagger docs are available at http://localhost:3000/api-docs.
- Start the server and navigate to
/api-docsfor interactive documentation - Create a new quiz with
POST /api/quizzes(optionally filter by category and difficulty) - Answer each question using the
quizIdreturned from the quiz creation - Submit answers one by one with
POST /api/quizzes/:quizId/answer - After answering all questions, view your score with
GET /api/quizzes/:quizId/score
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
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
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 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.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/questions |
List all questions (supports category, difficulty, page, limit) |
| GET | /api/questions/:id |
Get a single question by ID |
| POST | /api/questions |
Create a new question with options |
| DELETE | /api/questions/:id |
Delete a question |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/quizzes |
Start a new quiz session |
| 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 |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api |
API info and available routes |
| GET | /api-docs |
Swagger UI interactive documentation |
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 }
]
}When starting a quiz, specify the number of questions:
{
"totalQuestions": 10,
"category": "javascript",
"difficulty": "hard"
}| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Server port |
NODE_ENV |
development |
Environment mode |
DB_PATH |
./data/quiz.db |
SQLite database file path |
- ✅ RESTful API with Express.js
- ✅ SQLite database with schema migrations
- ✅ Full CRUD for questions
- ✅ Quiz session management with UUID
- ✅ Random question selection (Fisher-Yates)
- ✅ Option shuffling per question
- ✅ Category and difficulty filtering
- ✅ Pagination for question listing
- ✅ Input validation middleware
- ✅ Centralized error handling
- ✅ Swagger API documentation
- ✅ Database seeding with sample questions
- ✅ Render.com deployment ready
- 🔮 [ ] Timed quizzes with countdown
- 🔮 [ ] Leaderboard and user tracking
- 🔮 [ ] Question update (PUT) endpoint
- 🔮 [ ] Quiz history and statistics
- 🔮 [ ] Bulk question import (CSV/JSON)
- Fork the repository
- Create your feature branch:
git checkout -b feat/amazing-feature - Commit your changes:
git commit -m "feat: add amazing feature" - Push to the branch:
git push origin feat/amazing-feature - Open a Pull Request
feat:— New featurefix:— Bug fixrefactor:— Code refactoringdocs:— Documentation changeschore:— Maintenance tasks
This project is licensed under the MIT License. See the LICENSE file for details.
- Express.js — Web framework
- better-sqlite3 — SQLite driver
- Swagger UI Express — API documentation
- Render — Cloud hosting platform
Serkanby
- Website: serkanbayraktar.com
- GitHub: @Serkanbyx
- Email: serkanbyx1@gmail.com
⭐ If you like this project, don't forget to give it a star!