# Job Board Backend API (MongoDB)
A complete backend system for managing jobs and applications with REST and GraphQL APIs,
built with Express.js, MongoDB, and TypeScript.
## Features
- **REST API**
- **GraphQL API** with queries and mutations
- **MongoDB** database integration
- **TypeScript** type safety
- **Zod** validation schemas
- MVC architecture pattern
- Comprehensive error handling
- Environment configuration
## Technologies
- Node.js
- Express.js
- TypeScript
- MongoDB
- Zod
- Apollo Server (GraphQL)
- Postman (Testing)
- Mongoose (ODM)
-
Clone the repository
git clone https://github.com/yourusername/job-board-backend-mongodb.git cd job-board-mongodb
-
Install dependencies
npm install
-
Environment Configuration Create
.env
file in root directory:MONGO_URI=mongodb://localhost:27017/job-board PORT=4000
-
Install MongoDB
brew tap mongodb/brew brew install mongodb-community
-
Start Service
brew services start mongodb-community
-
Create Database
mongosh use job-board exit
- Download installer from MongoDB Community Server
- Install with default settings
- Open bash:
mkdir C:\data\db # Create the data directory
"C:\Program Files\MongoDB\Server\5.0\bin\mongod.exe" # Start MongoDB server (replace 5.0 with your version)
"C:\Program Files\MongoDB\Server\5.0\bin\mongosh.exe" # Access MongoDB shell
# Optional: Run MongoDB as a service
"C:\Program Files\MongoDB\Server\5.0\bin\mongod.exe" --config "C:\Program Files\MongoDB\Server\5.0\mongod.cfg" --install # Install MongoDB as service
net start MongoDB # Start MongoDB service
Development mode:
npm run start:dev
Production build:
npm run build
npm run start:prod
- Import the Postman collection from
/postman
directory
- Download the Postman Job Board collection and import it into Postman.
- Download the Postman Job Board Environment and import it into Postman.
- Or Manually Set up environment variables
after importing job board collection:
jb-local-url
:http://localhost:4000/api/v1
http://localhost:4000/api/v1
POST /jobs
Request Body:
{
"title": "Senior Developer",
"description": "Node.js backend development position",
"company": "Tech Corp",
"location": "Remote"
}
Success Response (201):
{
"success": true,
"statusCode": 201,
"message": "Job created successfully",
"data": {
"_id": "65d5f8a9c8b93912b4f4a491",
"title": "Senior Developer",
"description": "Node.js backend development position",
"company": "Tech Corp",
"location": "Remote",
"created_at": "2025-03-08T23:10:59.118Z"
}
}
GET /jobs
Success Response (200):
{
"success": true,
"statusCode": 200,
"message": "Jobs retrieved successfully",
"data": [
{
"_id": "65d5f8a9c8b93912b4f4a491",
"title": "Senior Developer",
"description": "Node.js backend development position",
"company": "Tech Corp",
"location": "Remote",
"applications": [
"67cd9805a04a24129c2dcd23",
"67cd9812a04a24129c2dcd27"
],
}
]
}
GET /jobs/:id
Success Response (200):
{
"success": true,
"statusCode": 200,
"message": "Job Found!",
"data":
{
"_id": "65d5f8a9c8b93912b4f4a491",
"title": "Senior Developer",
"description": "Node.js backend development position",
"company": "Tech Corp",
"location": "Remote",
"applications": [
{
"_id": "67cd9805a04a24129c2dcd23",
"job_id": "67cd97929b9d82646b2f383b",
"applicant_name": "Tom",
"applicant_email": "rex@example.com",
"cover_letter": "I have 1 years of experience...",
"submitted_at": "2025-03-09T13:30:45.444Z",
"__v": 0
},
],
}
}
POST /applications
Request Body:
{
"job_id": "65d5f8a9c8b93912b4f4a491",
"applicant_name": "John Doe",
"applicant_email": "john@example.com",
"cover_letter": "I have 5 years experience..."
}
Success Response (201):
{
"success": true,
"statusCode": 201,
"message": "Application submitted successfully",
"data": {
"_id": "65d5f8e3c8b93912b4f4a492",
"job_id": "65d5f8a9c8b93912b4f4a491",
"applicant_name": "John Doe",
"applicant_email": "john@example.com",
"cover_letter": "I have 5 years experience...",
"submitted_at": "2025-03-08T23:12:03.456Z"
}
}
POST /applications/:job_id
Success Response (200):
{
"success": true,
"statusCode": 201,
"message": "Applications retrieved successfully",
"data": [
{
"_id": "65d5f8e3c8b93912b4f4a492",
"job_id": "65d5f8a9c8b93912b4f4a491",
"applicant_name": "John Doe",
"applicant_email": "john@example.com",
"cover_letter": "I have 5 years experience...",
"submitted_at": "2025-03-08T23:12:03.456Z"
},
{
"_id": "67cd9805a04a24129c2dcd23",
"job_id": "65d5f8a9c8b93912b4f4a491",
"applicant_name": "Tom",
"applicant_email": "rex@example.com",
"cover_letter": "I have 1 years of experience...",
"submitted_at": "2025-03-09T13:30:45.444Z",
},
]
}
Access Playground: Open http://localhost:4000/graphql
in Google Chrome
or any modern browser to test your GraphQL queries. 🚀
query {
jobs {
id
title
description
applications {
applicant_name
submitted_at
}
}
}
Response:
{
"data": {
"jobs": [
{
"id": "65d5f8a9c8b93912b4f4a491",
"title": "Senior Developer",
"description": "Node.js position",
"applications": [
{
"applicant_name": "John Doe",
"submitted_at": "2025-03-08T23:12:03.456Z"
}
]
}
]
}
}
query {
job(id: "65d5f8a9c8b93912b4f4a491") {
id
title
description
company
applications {
applicant_name
submitted_at
}
}
}
Response:
{
"data": {
"job": {
"id": "65d5f8a9c8b93912b4f4a491",
"title": "Senior Developer",
"description": "Node.js position",
"company": "Tech Corp",
"applications": [
{
"applicant_name": "John Doe",
"submitted_at": "2023-10-05T12:45:00.000Z"
}
]
}
}
}
query {
applications(job_id: "65d5f8a9c8b93912b4f4a491") {
id
applicant_name
applicant_email
submitted_at
}
}
Response:
{
"data": {
"applications": [
{
"id": "65d5f8e3c8b93912b4f4a492",
"applicant_name": "John Doe",
"applicant_email": "john@example.com",
"submitted_at": "2023-10-05T12:45:00.000Z"
}
]
}
}
mutation {
createJob(input: {
title: "Frontend Developer",
description: "React specialist",
company: "Web Corp",
location: "Hybrid"
}) {
id
title
company
}
}
Response:
{
"data": {
"createJob": {
"id": "65d5f9b2c8b93912b4f4a493",
"title": "Frontend Developer",
"company": "Web Corp"
}
}
}
mutation {
createApplication(input: {
job_id: "65d5f9b2c8b93912b4f4a493",
applicant_name: "Alice Smith",
applicant_email: "alice@example.com",
cover_letter: "Experienced developer..."
}) {
id
applicant_name
}
}
Response:
{
"data": {
"createApplication": {
"id": "65d5f9b2c8b93912b4f4a499",
"applicant_name": "Alice Smith"
}
}
}
{
"success": false,
"statusCode": 400,
"message": "Validation Error",
"error": [
{
"path": "body.job_id",
"message": "Invalid Job ID"
}
]
}
{
"success": false,
"statusCode": 400,
"message": "Validation Error",
"error": [
{
"path": "body.company",
"message": "Expected string, received number"
}
]
}
{
"success": false,
"statusCode": 400,
"message": "Validation Error",
"data": null,
"error": [
{
"path": "body.company",
"message": "Company name must be at least 2 characters long"
}
]
}
{
"success": false,
"statusCode": 404,
"message": "No job record found for the provided Job ID!"
}
{
"success": false,
"statusCode": 404,
"message": "Job not found"
}
{
"success": false,
"statusCode": 500,
"message": "Internal Server Error"
}
{
"start:prod": "node ./dist/server.js",
"start:dev": "ts-node-dev --respawn --transpile-only src/server.ts",
"build": "tsc",
"lint": "eslint 'src/**/*.ts'",
"lint:fix": "npx eslint src --fix",
"prettier": "prettier --ignore-path .gitignore --write \"**/*.+(js|ts|json)\"",
"prettier:fix": "npx prettier --write src",
"test": "echo \"Error: no test specified\" && exit 1"
}
MongoDB Connection Issues:
# Verify MongoDB service status
brew services list # macOS
net start MongoDB # Windows
# Test connection
mongosh --eval "db.runCommand({ping:1})"
Reset Database:
mongosh job-board --eval "db.dropDatabase()"
Common Issues:
- Ensure MongoDB service is running
- Verify connection string in .env file
- Check for duplicate document IDs
- Validate all request bodies match Zod schemas