Skip to content

Bisha18/recepie_api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🍴 Recipe API

A robust RESTful API for the Recipe Spoon mobile application

Node.js Express MongoDB Deployed on Render License

Features β€’ Installation β€’ API Documentation β€’ Deployment

Live API Base URL: https://recepie-api.onrender.com/api


πŸ“– Overview

The Recipe API is a comprehensive backend service built with Node.js, Express.js, and MongoDB that powers the Recipe Spoon mobile application. It provides secure authentication, recipe management, user favorites, search functionality, and more.

Key Highlights

  • βœ… RESTful Architecture: Clean, standard API design
  • πŸ” JWT Authentication: Secure user authentication and authorization
  • πŸ“Š MongoDB Database: Scalable NoSQL database with Mongoose ODM
  • πŸš€ Production Ready: Deployed on Render with 99.9% uptime
  • πŸ“ Comprehensive Documentation: Well-documented endpoints
  • πŸ” Advanced Search: Full-text search and filtering
  • ⚑ Performance Optimized: Caching and query optimization

✨ Features

Core Functionality

  • User Authentication

    • User registration with email validation
    • Secure login with JWT tokens
    • Password hashing with bcrypt
    • Token-based session management
    • Password reset functionality
  • Recipe Management

    • Create, read, update, and delete recipes (CRUD)
    • Rich recipe data (ingredients, instructions, images, videos)
    • Recipe categorization and tagging
    • Nutritional information
    • Cooking time and difficulty levels
  • Search & Discovery

    • Full-text search across recipes
    • Filter by ingredients, cuisine, dietary preferences
    • Sort by popularity, rating, date
    • Advanced query parameters
  • User Features

    • Favorite/bookmark recipes
    • User recipe collections
    • Recipe ratings and reviews
    • User profiles and preferences
  • Media Handling

    • Image upload and storage
    • Video URL integration
    • Cloudinary integration for media optimization

Additional Features

  • Rate Limiting: Prevent API abuse
  • Error Handling: Comprehensive error responses
  • Validation: Request data validation with express-validator
  • CORS: Cross-origin resource sharing enabled
  • Logging: Request and error logging
  • Health Check: Endpoint for monitoring

πŸš€ Installation

Prerequisites

  • Node.js (v18 or higher)
  • MongoDB (v6 or higher)
  • npm or yarn package manager
  • MongoDB Atlas account (for cloud database) or local MongoDB

Step-by-Step Setup

  1. Clone the Repository

    git clone https://github.com/Bisha18/recepie_api.git
    cd recepie_api
  2. Install Dependencies

    npm install
  3. Environment Configuration

    Create a .env file in the root directory:

    # Server Configuration
    NODE_ENV=development
    PORT=5000
    
    # Database
    MONGODB_URI=mongodb://localhost:27017/recipe_db
    # OR for MongoDB Atlas:
    # MONGODB_URI=mongodb+srv://<username>:<password>@cluster.mongodb.net/recipe_db
    
    # JWT Secret (use a strong random string)
    JWT_SECRET=your_super_secret_jwt_key_here
    JWT_EXPIRE=7d
    
    # Cloudinary (Optional - for image uploads)
    CLOUDINARY_CLOUD_NAME=your_cloud_name
    CLOUDINARY_API_KEY=your_api_key
    CLOUDINARY_API_SECRET=your_api_secret
    
    # Email Configuration (Optional - for password reset)
    EMAIL_HOST=smtp.gmail.com
    EMAIL_PORT=587
    EMAIL_USER=your_email@gmail.com
    EMAIL_PASSWORD=your_app_password
    
    # Rate Limiting
    RATE_LIMIT_WINDOW_MS=900000
    RATE_LIMIT_MAX_REQUESTS=100
    
    # CORS
    ALLOWED_ORIGINS=http://localhost:19006,https://recipie-spoon.app
  4. Database Setup

    Make sure MongoDB is running:

    # For local MongoDB
    mongod
    
    # For MongoDB Atlas, just ensure your connection string is correct
  5. Seed Database (Optional)

    npm run seed
  6. Start Development Server

    # Development mode with nodemon
    npm run dev
    
    # Production mode
    npm start
  7. Verify Installation

    curl http://localhost:5000/api/health

πŸ“ Project Structure

recepie_api/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ config/              # Configuration files
β”‚   β”‚   β”œβ”€β”€ database.js      # MongoDB connection
β”‚   β”‚   β”œβ”€β”€ cloudinary.js    # Cloudinary setup
β”‚   β”‚   └── email.js         # Email service config
β”‚   β”œβ”€β”€ controllers/         # Route controllers
β”‚   β”‚   β”œβ”€β”€ authController.js
β”‚   β”‚   β”œβ”€β”€ recipeController.js
β”‚   β”‚   β”œβ”€β”€ userController.js
β”‚   β”‚   └── favoriteController.js
β”‚   β”œβ”€β”€ models/             # Mongoose models
β”‚   β”‚   β”œβ”€β”€ User.js
β”‚   β”‚   β”œβ”€β”€ Recipe.js
β”‚   β”‚   β”œβ”€β”€ Favorite.js
β”‚   β”‚   └── Review.js
β”‚   β”œβ”€β”€ routes/            # API routes
β”‚   β”‚   β”œβ”€β”€ auth.js
β”‚   β”‚   β”œβ”€β”€ recipes.js
β”‚   β”‚   β”œβ”€β”€ users.js
β”‚   β”‚   └── favorites.js
β”‚   β”œβ”€β”€ middleware/        # Custom middleware
β”‚   β”‚   β”œβ”€β”€ auth.js        # JWT authentication
β”‚   β”‚   β”œβ”€β”€ errorHandler.js
β”‚   β”‚   β”œβ”€β”€ validate.js    # Request validation
β”‚   β”‚   └── rateLimiter.js
β”‚   β”œβ”€β”€ utils/            # Utility functions
β”‚   β”‚   β”œβ”€β”€ emailService.js
β”‚   β”‚   β”œβ”€β”€ generateToken.js
β”‚   β”‚   └── validators.js
β”‚   β”œβ”€β”€ seeds/            # Database seeders
β”‚   β”‚   └── recipeSeed.js
β”‚   └── app.js           # Express app setup
β”œβ”€β”€ tests/               # Test files
β”‚   β”œβ”€β”€ auth.test.js
β”‚   β”œβ”€β”€ recipes.test.js
β”‚   └── users.test.js
β”œβ”€β”€ .env.example        # Environment variables template
β”œβ”€β”€ .gitignore
β”œβ”€β”€ package.json
β”œβ”€β”€ server.js          # Entry point
└── README.md

πŸ“š API Documentation

Base URL

Development: http://localhost:5000/api
Production: https://recepie-api.onrender.com/api

Authentication

All authenticated endpoints require a JWT token in the Authorization header:

Authorization: Bearer <your_jwt_token>

πŸ” Authentication Endpoints

Register User

POST /api/auth/register

Request Body:

{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "SecurePassword123!",
  "confirmPassword": "SecurePassword123!"
}

Response: 201 Created

{
  "success": true,
  "message": "User registered successfully",
  "data": {
    "user": {
      "_id": "64f7b8c9e1234567890abcde",
      "name": "John Doe",
      "email": "john@example.com",
      "createdAt": "2024-01-15T10:30:00.000Z"
    },
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

Login User

POST /api/auth/login

Request Body:

{
  "email": "john@example.com",
  "password": "SecurePassword123!"
}

Response: 200 OK

{
  "success": true,
  "message": "Login successful",
  "data": {
    "user": {
      "_id": "64f7b8c9e1234567890abcde",
      "name": "John Doe",
      "email": "john@example.com"
    },
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

Get Current User

GET /api/auth/me

Headers: Authorization: Bearer <token>

Response: 200 OK

{
  "success": true,
  "data": {
    "_id": "64f7b8c9e1234567890abcde",
    "name": "John Doe",
    "email": "john@example.com",
    "favorites": [],
    "createdAt": "2024-01-15T10:30:00.000Z"
  }
}

Request Password Reset

POST /api/auth/forgot-password

Request Body:

{
  "email": "john@example.com"
}

🍽️ Recipe Endpoints

Get All Recipes

GET /api/recipes

Query Parameters:

  • page (number): Page number (default: 1)
  • limit (number): Items per page (default: 20)
  • search (string): Search term
  • category (string): Filter by category
  • cuisine (string): Filter by cuisine type
  • difficulty (string): easy | medium | hard
  • maxTime (number): Maximum cooking time in minutes
  • sort (string): Sort field (e.g., -createdAt, rating)

Example:

GET /api/recipes?search=pasta&category=italian&limit=10&page=1

Response: 200 OK

{
  "success": true,
  "count": 45,
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 45,
    "pages": 5
  },
  "data": [
    {
      "_id": "64f7b8c9e1234567890abcde",
      "title": "Classic Spaghetti Carbonara",
      "description": "A traditional Italian pasta dish...",
      "image": "https://cloudinary.com/recipes/carbonara.jpg",
      "videoUrl": "https://youtube.com/watch?v=...",
      "prepTime": 10,
      "cookTime": 20,
      "servings": 4,
      "difficulty": "medium",
      "category": "italian",
      "cuisine": "Italian",
      "ingredients": [
        {
          "name": "Spaghetti",
          "quantity": "400",
          "unit": "g"
        },
        {
          "name": "Eggs",
          "quantity": "4",
          "unit": "whole"
        }
      ],
      "instructions": [
        {
          "step": 1,
          "description": "Bring a large pot of salted water to boil..."
        }
      ],
      "nutrition": {
        "calories": 450,
        "protein": 25,
        "carbs": 55,
        "fat": 15
      },
      "tags": ["pasta", "italian", "classic"],
      "author": {
        "_id": "64f7b8c9e1234567890abcde",
        "name": "Chef Mario"
      },
      "rating": 4.8,
      "reviewsCount": 156,
      "createdAt": "2024-01-15T10:30:00.000Z",
      "updatedAt": "2024-01-20T15:45:00.000Z"
    }
  ]
}

Get Recipe by ID

GET /api/recipes/:id

Response: 200 OK

{
  "success": true,
  "data": {
    "_id": "64f7b8c9e1234567890abcde",
    "title": "Classic Spaghetti Carbonara",
    // ... full recipe details
  }
}

Search Recipes

GET /api/recipes/search?q=chicken

Query Parameters:

  • q (string): Search query (required)
  • limit (number): Results limit

Response: 200 OK

Create Recipe (Auth Required)

POST /api/recipes

Headers: Authorization: Bearer <token>

Request Body:

{
  "title": "Homemade Pizza Margherita",
  "description": "Authentic Italian pizza with fresh mozzarella",
  "image": "https://cloudinary.com/...",
  "videoUrl": "https://youtube.com/...",
  "prepTime": 30,
  "cookTime": 15,
  "servings": 4,
  "difficulty": "medium",
  "category": "italian",
  "cuisine": "Italian",
  "ingredients": [
    {
      "name": "Pizza dough",
      "quantity": "500",
      "unit": "g"
    },
    {
      "name": "Tomato sauce",
      "quantity": "200",
      "unit": "ml"
    }
  ],
  "instructions": [
    {
      "step": 1,
      "description": "Preheat oven to 250Β°C..."
    }
  ],
  "nutrition": {
    "calories": 280,
    "protein": 12,
    "carbs": 35,
    "fat": 10
  },
  "tags": ["pizza", "italian", "vegetarian"]
}

Response: 201 Created

Update Recipe (Auth Required)

PUT /api/recipes/:id

Headers: Authorization: Bearer <token>

Request Body: (Same as create, with fields to update)

Response: 200 OK

Delete Recipe (Auth Required)

DELETE /api/recipes/:id

Headers: Authorization: Bearer <token>

Response: 200 OK

{
  "success": true,
  "message": "Recipe deleted successfully"
}

❀️ Favorites Endpoints

Get User Favorites

GET /api/favorites

Headers: Authorization: Bearer <token>

Response: 200 OK

{
  "success": true,
  "count": 5,
  "data": [
    {
      "_id": "64f7b8c9e1234567890abcde",
      "recipe": {
        "_id": "64f7b8c9e1234567890abcdf",
        "title": "Classic Spaghetti Carbonara",
        "image": "https://...",
        "rating": 4.8
      },
      "addedAt": "2024-01-15T10:30:00.000Z"
    }
  ]
}

Add to Favorites

POST /api/favorites/:recipeId

Headers: Authorization: Bearer <token>

Response: 201 Created

Remove from Favorites

DELETE /api/favorites/:recipeId

Headers: Authorization: Bearer <token>

Response: 200 OK


πŸ‘€ User Endpoints

Get User Profile

GET /api/users/profile

Headers: Authorization: Bearer <token>

Update User Profile

PUT /api/users/profile

Headers: Authorization: Bearer <token>

Request Body:

{
  "name": "John Updated",
  "bio": "Food enthusiast and home chef",
  "avatar": "https://cloudinary.com/avatar.jpg",
  "preferences": {
    "dietaryRestrictions": ["vegetarian"],
    "cuisinePreferences": ["italian", "japanese"]
  }
}

Get User's Recipes

GET /api/users/my-recipes

Headers: Authorization: Bearer <token>


πŸ“Š Additional Endpoints

Get Recipe Categories

GET /api/categories

Response: 200 OK

{
  "success": true,
  "data": [
    "Italian",
    "Mexican",
    "Chinese",
    "Indian",
    "Japanese",
    "Mediterranean"
  ]
}

Get Popular Recipes

GET /api/recipes/popular

Response: Similar to Get All Recipes

Health Check

GET /api/health

Response: 200 OK

{
  "success": true,
  "message": "API is running",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "uptime": 86400,
  "database": "connected"
}

πŸ”’ Security Features

Authentication & Authorization

  • JWT Tokens: Secure stateless authentication
  • Password Hashing: Bcrypt with salt rounds
  • Token Expiration: Automatic session timeout
  • Role-Based Access: Admin and user roles

Request Security

  • Rate Limiting: Prevent brute force attacks
  • CORS: Configured allowed origins
  • Helmet: HTTP headers security
  • Input Validation: Sanitization and validation
  • SQL Injection Protection: Mongoose parameterized queries
  • XSS Protection: Content Security Policy

Environment Security

  • Environment Variables: Sensitive data in .env
  • Secrets Management: Never commit secrets
  • HTTPS Only: Enforced in production

πŸ§ͺ Testing

# Run all tests
npm test

# Run tests with coverage
npm run test:coverage

# Run integration tests
npm run test:integration

# Run specific test file
npm test -- auth.test.js

Test Structure

// Example test
describe('Auth Controller', () => {
  describe('POST /api/auth/register', () => {
    it('should register a new user', async () => {
      const response = await request(app)
        .post('/api/auth/register')
        .send({
          name: 'Test User',
          email: 'test@example.com',
          password: 'Password123!'
        });
      
      expect(response.status).toBe(201);
      expect(response.body.success).toBe(true);
      expect(response.body.data).toHaveProperty('token');
    });
  });
});

πŸš€ Deployment

Deploy to Render

  1. Create Render Account

  2. Create New Web Service

    • Connect your GitHub repository
    • Select the backend repository
  3. Configure Build Settings

    Build Command: npm install
    Start Command: npm start
    
  4. Add Environment Variables

    • Add all variables from .env file
    • Make sure to use production values
  5. Deploy

    • Click "Create Web Service"
    • Render will automatically deploy

Deploy to Heroku

# Login to Heroku
heroku login

# Create new app
heroku create recepie-api

# Add MongoDB addon
heroku addons:create mongolab:sandbox

# Set environment variables
heroku config:set JWT_SECRET=your_secret_here

# Deploy
git push heroku main

# Open app
heroku open

Deploy to AWS EC2

  1. Launch EC2 instance (Ubuntu)
  2. SSH into instance
  3. Install Node.js and MongoDB
  4. Clone repository
  5. Install dependencies
  6. Set up PM2 for process management
  7. Configure Nginx as reverse proxy
  8. Set up SSL with Let's Encrypt

πŸ“Š Performance Optimization

  • Database Indexing: Indexes on frequently queried fields
  • Query Optimization: Efficient MongoDB queries
  • Caching: Redis for frequently accessed data
  • Pagination: Limit data transfer
  • Compression: Gzip compression enabled
  • CDN: Cloudinary for media delivery

πŸ› Error Handling

All errors follow a consistent format:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Email is required",
    "statusCode": 400,
    "details": {
      "field": "email",
      "value": ""
    }
  }
}

Error Codes

  • 400 - Bad Request
  • 401 - Unauthorized
  • 403 - Forbidden
  • 404 - Not Found
  • 409 - Conflict (duplicate)
  • 422 - Validation Error
  • 429 - Too Many Requests
  • 500 - Internal Server Error

πŸ“ Logging

Logs are written to:

  • Console (development)
  • Log files (production)
  • External service (optional)
// Example log format
{
  "timestamp": "2024-01-15T10:30:00.000Z",
  "level": "info",
  "method": "GET",
  "path": "/api/recipes",
  "statusCode": 200,
  "responseTime": "45ms",
  "userId": "64f7b8c9e1234567890abcde"
}

πŸ”„ Database Schema

User Model

{
  name: String (required),
  email: String (required, unique),
  password: String (required, hashed),
  avatar: String,
  bio: String,
  role: String (default: 'user'),
  preferences: {
    dietaryRestrictions: [String],
    cuisinePreferences: [String]
  },
  createdAt: Date,
  updatedAt: Date
}

Recipe Model

{
  title: String (required),
  description: String (required),
  image: String,
  videoUrl: String,
  prepTime: Number,
  cookTime: Number,
  servings: Number,
  difficulty: String (enum: easy/medium/hard),
  category: String,
  cuisine: String,
  ingredients: [{
    name: String,
    quantity: String,
    unit: String
  }],
  instructions: [{
    step: Number,
    description: String
  }],
  nutrition: {
    calories: Number,
    protein: Number,
    carbs: Number,
    fat: Number
  },
  tags: [String],
  author: ObjectId (ref: User),
  rating: Number,
  reviewsCount: Number,
  createdAt: Date,
  updatedAt: Date
}

🀝 Contributing

Contributions are welcome! Please follow these guidelines:

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

Code Style

  • Use ES6+ features
  • Follow Airbnb JavaScript Style Guide
  • Write meaningful comments
  • Add JSDoc documentation for functions

πŸ“„ License

This project is licensed under the MIT License - see LICENSE file.


πŸ‘¨β€πŸ’» Author

Bisha18


πŸ™ Acknowledgments


πŸ“ž Support

For issues or questions:


Made with ❀️ and Node.js

Live API: https://recepie-api.onrender.com/api

⬆ Back to Top

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors