How watermelon-music/watermelon-api works
Purpose and entry points
Watermelon API is a Node.js/Express REST backend for an Android music app. It searches YouTube, derives audio stream/download URLs through yt-dlp, exposes radio and recommendation APIs, and supports subscription payments and app statistics. Runtime startup is server.js, which boots the Express application in src/app.js.
HTTP composition and cross-cutting boundary
src/app.js assembles the API: security/CORS/compression, request logging, IP rate limiting, route mounting, and centralized failure handling. The middleware boundary keeps controllers focused on request/response orchestration.
• src/middlewares/rateLimit.middleware.js
• src/middlewares/logger.middleware.js
• src/middlewares/error.middleware.js
Music discovery and extraction pipeline
Search, song metadata, direct streaming, and download requests enter route-specific handlers and converge on the yt-dlp integration. The service invokes the bundled/downloaded yt-dlp executable to query YouTube and extract playable audio URLs; controllers transform results into API responses.
• src/routes/search.routes.js
• src/controllers/song.controller.js
• src/services/ytdlp.service.js
The yt-dlp binary is provisioned at install/build time by scripts/download-ytdlp.js; the repository includes bin/yt-dlp.exe for Windows.
Content and client-facing API domains
Routes separate public API domains: search/song lookup, stream/download delivery, artists, radio, leaderboards, stats, authentication, and recommendations. This is an HTTP API rather than a web UI; the Android client is the primary consumer.
• src/routes/song.routes.js
• src/routes/stream.routes.js
• src/routes/download.routes.js
Radio search/station browsing depends on the external Radio Browser service; AI recommendations depend on Gemini, per the API contract.
Persistence, caching, and engagement
Supabase is the system of record, using the supplied service-role configuration for users, playlists/favorites, listening statistics, premium state, and documented gamification data. The schema lives in supabase_setup.sql. In-memory caching reduces repeated yt-dlp/search and metadata work; scheduled/background behavior is centralized separately.
• supabase_setup.sql
• src/services/cache.service.js
• src/services/cronService.js
Payments and asynchronous integrations
Payment endpoints create orders, present checkout, verify status, and receive server-to-server webhooks through Cashfree. Payment-specific controller logic is isolated from the provider adapter. Optional Telegram bot and notification services provide external control and outbound messaging.
• src/routes/payment.routes.js
• src/controllers/cashfree.controller.js
• src/services/razorpay.service.js
Note the repository names the available adapter razorpay.service.js while the README/API describe Cashfree; this provider mismatch is an integration point to validate.
Deployment/runtime boundaries
Node.js LTS (18+) runs the service. Deployments target Render through render.yaml, Docker through Dockerfile, or self-hosted environments. Required external configuration includes Supabase; Cashfree and Telegram are optional. Render/Docker build steps explicitly download yt-dlp before starting server.js.
• render.yaml
• Dockerfile
• .env.example
Main entry points: app.js Express app · song.controller.js Song controller · yt-dlp.exe yt-dlp executable · server.js Server startup
Components 21
HTTP API
Express routes, controllers, and middleware.
- Express app · Mounts routes and centralized middleware.
src/app.js - Middleware boundary · Rate limiting, request logging, and failure handling.
- API route domains · Search, songs, streams, downloads, artists, radio, stats, auth, and recommendations.
- Song controller · Transforms music lookup and extraction results into responses.
src/controllers/song.controller.js - Payment routes
src/routes/payment.routes.js - Payment controller
src/controllers/cashfree.controller.js
Music pipeline
YouTube discovery and audio extraction.
- yt-dlp service · Invokes yt-dlp for YouTube metadata and playable audio URLs.
src/services/ytdlp.service.js - yt-dlp executable
bin/yt-dlp.exe - YouTube
- In-memory cache · Avoids repeated search and metadata extraction.
src/services/cache.service.js
External integrations
Persistence and provider boundaries.
- Supabase · Stores users, music data, engagement, and premium state.
- Supabase schema
supabase_setup.sql - Radio Browser
- Gemini
- Razorpay adapter · Named adapter differs from the documented Cashfree integration.
src/services/razorpay.service.js - Cashfree · Checkout, status, and webhook integration target.
Runtime and deployment
Service startup and yt-dlp provisioning.
- Server startup
server.js - Scheduled jobs
src/services/cronService.js - yt-dlp provisioning · Downloads the executable during install or build.
scripts/download-ytdlp.js - Render / Docker · Builds provision yt-dlp before starting Node.
Other components
- Android client
Connections 22
- Android client → Server startup: HTTPS requests
- Server startup → Express app: boots
- Express app → Middleware boundary: applies
- Middleware boundary → API route domains: passes requests
- Express app → API route domains: mounts
- API route domains → Song controller: music requests
- Song controller → In-memory cache: reads and writes
- Song controller → yt-dlp service: searches and extracts
- yt-dlp service → yt-dlp executable: executes
- yt-dlp executable → YouTube: queries
- API route domains → Supabase: users and engagement
- Supabase schema → Supabase: defines
- API route domains → Radio Browser: radio browsing
- API route domains → Gemini: recommendations
- API route domains → Payment routes: payment endpoints
- Payment routes → Payment controller: dispatches
- Payment controller → Razorpay adapter: uses
- Razorpay adapter → Cashfree: provider target to validate
- Scheduled jobs → Supabase: background work
- Render / Docker → yt-dlp provisioning: build step
- yt-dlp provisioning → yt-dlp executable: downloads
- Render / Docker → Server startup: starts