Skip to content

Latest commit

Β 

History

History
572 lines (436 loc) Β· 10.7 KB

File metadata and controls

572 lines (436 loc) Β· 10.7 KB

πŸ’§ Mobinime API

Hono Node.js REST API Status

Lightweight REST API wrapper for Mobinime anime streaming platform

Built with Hono (JS, ESM) β€’ Easy integration with WhatsApp bots, frontends & automation tools


Table of Contents


✨ Features

Core Features

  • Homepage Data - Fetch latest anime updates

  • Genre List - Get all available genres

  • Anime List - Filter by type & genre

  • Search - Find anime by query

  • Anime Details - Complete anime information

  • Streaming URLs - Get episode streaming links

Technical Features

  • Lightweight - Built with Hono framework

  • Modular - Easy to extend & customize

  • Serverless Ready - Deploy anywhere

  • Type Safe - Structured request/response

  • Error Handling - Consistent error responses

  • Cache Ready - Built-in caching support


Quick Start

Prerequisites

Node.js >= 18.x
npm or yarn or pnpm

Installation

# Clone the repository
git clone https://github.com/yourusername/mobinime-api.git

# Navigate to directory
cd mobinime-api

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env

# Start development server
npm run dev

Health Check

curl http://localhost:3000/

Response:

{
  "status": true,
  "message": "Mobinime API running"
}

πŸ“‘ API Endpoints

Base URL

https://your-api-domain.com
GET /homepage

Get homepage data with latest anime updates.

Response:

{
  "status": true,
  "data": {
    "ongoing": [...],
    "completed": [...],
    "popular": [...]
  }
}
GET /genres

Retrieve all available anime genres.

Response:

{
  "status": true,
  "data": [
    { "id": "1", "title": "Action" },
    { "id": "2", "title": "Comedy" },
    { "id": "3", "title": "Drama" }
  ]
}
πŸ“š GET /anime/:type

Get anime list filtered by type and genre.

Valid Types: series | movie | ova | live-action

Query Parameters:

Parameter Type Default Description
page number 0 Page number
count number 15 Items per page
genre string - Genre slug (e.g., "action")

Example:

GET /anime/series?genre=action&page=0&count=15

Response:

{
  "status": true,
  "data": {
    "perpage": 15,
    "startpage": 0,
    "total": 1200,
    "items": [
      {
        "id": "1001",
        "title": "Anime Title",
        "thumb": "https://...",
        "rating": "8.5"
      }
    ]
  }
}
GET /search

Search anime by query string.

Query Parameters:

Parameter Type Required Description
q string βœ… Yes Search query
page number No Page number
count number No Items per page

Example:

GET /search?q=naruto&page=0&count=10

Response:

{
  "status": true,
  "data": {
    "results": [
      {
        "id": "123",
        "title": "Naruto Shippuden",
        "thumb": "https://..."
      }
    ]
  }
}
GET /detail/:id

Get detailed information about a specific anime.

Example:

GET /detail/123

Response:

{
  "status": true,
  "data": {
    "id": "123",
    "title": "Anime Title",
    "description": "...",
    "genres": ["Action", "Adventure"],
    "episodes": [
      { "id": "456", "title": "Episode 1" }
    ],
    "staff": {...},
    "rating": "8.5"
  }
}
GET /stream

Get streaming URL for a specific episode.

Query Parameters:

Parameter Type Required Description
id string βœ… Yes Anime ID
epsid string βœ… Yes Episode ID
quality string No Quality (HD/SD)

Example:

GET /stream?id=123&epsid=456&quality=HD

Response:

{
  "status": true,
  "url": "https://streaming-url.com/video.m3u8"
}

Error Response (404):

{
  "status": false,
  "error": {
    "code": 404,
    "message": "Stream URL not found"
  }
}

Configuration

Environment Variables

Create a .env file in the root directory:

# API Configuration
MOBINIME_BASE_URL=https://air.vunime.my.id/mobinime
MOBINIME_API_KEY=your-api-key-here
MOBINIME_USER_AGENT=Mozilla/5.0...

# Caching
CACHE_PROVIDER=redis  # redis | memory
REDIS_URL=redis://localhost:6379

# Rate Limiting
RATE_LIMIT=60  # requests per minute

# Server
PORT=3000
NODE_ENV=production

# Logging
LOG_LEVEL=info  # info | debug | warn | error

Validation Rules

  • type: Must be one of series, movie, ova, live-action
  • page: Integer >= 0
  • count: Integer >= 0
  • genre: Valid genre slug from genre list
  • id: Numeric string

Caching & Performance

Recommended TTL Strategy

const CACHE_TTL = {
  genres: 86400,      // 24 hours
  homepage: 1800,     // 30 minutes
  animeList: 900,     // 15 minutes
  detail: 3600,       // 1 hour
  stream: 300         // 5 minutes
};

Cache Key Pattern

mobinime:genres
mobinime:animeList:${type}:${genre}:${page}:${count}
mobinime:detail:${id}
mobinime:stream:${id}:${epsid}:${quality}

Rate Limiting

  • Public Endpoints: 60 requests/minute per IP
  • Search Endpoint: 30 requests/minute per IP
  • Stream Endpoint: 100 requests/minute per IP

Security

Security Measure Implementation
API Keys Never commit to repository
Timeouts 8-12s for external requests
Input Sanitization All user inputs validated
Rate Limiting IP & API key based throttling
CORS Restricted to trusted origins
HTTPS Required in production

Best Practices

// βœ… DO: Use environment variables
const baseURL = process.env.MOBINIME_BASE_URL;

// ❌ DON'T: Hardcode secrets
const apiKey = "abc123..."; // Never do this!

// βœ… DO: Set timeouts
axios.get(url, { timeout: 10000 });

// βœ… DO: Validate inputs
if (!['series', 'movie', 'ova', 'live-action'].includes(type)) {
  throw new Error('Invalid type');
}

Examples

JavaScript (Fetch)

// Search for anime
const searchAnime = async (query) => {
  const response = await fetch(
    `https://api.example.com/search?q=${encodeURIComponent(query)}&page=0&count=10`
  );
  const data = await response.json();
  return data;
};

// Get streaming URL
const getStreamURL = async (animeId, episodeId) => {
  const response = await fetch(
    `https://api.example.com/stream?id=${animeId}&epsid=${episodeId}&quality=HD`
  );
  const data = await response.json();
  return data.url;
};

Node.js (Axios)

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000
});

// Get anime list
const getAnimeList = async (type, genre, page = 0) => {
  const { data } = await api.get(`/anime/${type}`, {
    params: { genre, page, count: 15 }
  });
  return data;
};

// Get anime details
const getAnimeDetail = async (id) => {
  const { data } = await api.get(`/detail/${id}`);
  return data;
};

cURL

# Get genres
curl -X GET "https://api.example.com/genres"

# Search anime
curl -X GET "https://api.example.com/search?q=naruto&page=0&count=10"

# Get stream URL
curl -X GET "https://api.example.com/stream?id=123&epsid=456&quality=HD"

Testing

Run Tests

# Unit tests
npm run test

# Integration tests
npm run test:integration

# Coverage report
npm run test:coverage

Test Structure

tests/
β”œβ”€β”€ unit/
β”‚   β”œβ”€β”€ validators.test.js
β”‚   β”œβ”€β”€ mappers.test.js
β”‚   └── utils.test.js
β”œβ”€β”€ integration/
β”‚   β”œβ”€β”€ endpoints.test.js
β”‚   └── cache.test.js
└── e2e/
    └── flow.test.js

Roadmap

  • Core API endpoints
  • Error handling
  • Redis caching integration
  • API key authentication
  • Rate limiting middleware
  • OpenAPI/Swagger documentation
  • Circuit breaker pattern
  • GraphQL wrapper
  • Monitoring & alerting
  • Multi-provider fallback

Status Codes

Code Description
200 βœ… Success
400 ❌ Bad Request - Invalid parameters
404 ❌ Not Found - Resource doesn't exist
429 ❌ Too Many Requests - Rate limit exceeded
500 ❌ Internal Server Error

Contributing

Contributions are welcome! Please follow these guidelines:

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

Code Standards

  • βœ… Follow ESLint rules
  • βœ… Write tests for new features
  • βœ… Update documentation
  • βœ… Keep PRs small and focused

License

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


⚠️ Disclaimer

This API wraps endpoints from air.vunime.my.id/mobinime which is not owned by this project. Please ensure your usage complies with the upstream Terms of Service and does not constitute abuse.


Acknowledgements

  • Built with Hono - Ultrafast web framework
  • HTTP client powered by Axios
  • Data source: air.vunime.my.id/mobinime

Made with ❀️ by Ryuhan, for developers

Report Bug Request Feature