Production-ready API that ingests public GitHub profile data, derives actionable insights, persists results in MySQL, and exposes a versioned HTTP interface for analysis, retrieval, comparison, and discovery.
| Live API | https://midaksh-github-analyzer-api.onrender.com |
| Source | github.com/midaksh/github-analyzer-api |
| Documentation | Project documentation (Notion) |
Given a GitHub username, the service aggregates data from the GitHub REST API and GraphQL API, computes profile-level metrics, stores a durable snapshot in MySQL, and serves it through a consistent JSON API under /api/v1.
| Runtime | Node.js 18+, Express.js |
| Persistence | MySQL 8 |
| Integrations | GitHub REST · GitHub GraphQL |
flowchart LR
Client["Client\nBrowser · Postman · curl"]
API["Express API\nNode.js"]
MySQL["MySQL"]
GH_REST["GitHub REST\nusers · repos · search"]
GH_GQL["GitHub GraphQL\ncontributions · repos"]
Client -->|HTTP| API
API -->|SQL| MySQL
API -->|HTTPS| GH_REST
API -->|HTTPS + token| GH_GQL
sequenceDiagram
participant C as Client
participant A as Express API
participant R as GitHub REST
participant G as GitHub GraphQL
participant D as MySQL
C->>A: POST /api/v1/profiles/analyze
A->>R: GET /users/{username}
A->>R: GET /users/{username}/repos
A->>G: contributions + recent repos
A->>A: Compute insights
A->>D: UPSERT github_profiles
A-->>C: 201 + profile JSON
Design notes: Stateless API layer · connection pooling for MySQL · upsert semantics on re-analysis · environment-driven configuration for local and cloud targets.
| Requirement | How this project delivers it |
|---|---|
| Fetch public profile data from GitHub using username | POST /api/v1/profiles/analyze with { "username": "..." } — calls GitHub REST (GET /users/{username}, GET /users/{username}/repos) and GraphQL for extended analytics |
| Store useful insights (e.g. public repo count, followers count, etc.) | Persists followers, following, public_repo_count, total stars/forks, languages, account age, contribution metrics, recent repos, and more in MySQL |
| Store analysis results in MySQL | Table github_profiles with upsert on re-analyze; schema in schema.sql |
| API to fetch all stored analyzed profile list | GET /api/v1/profiles — returns all profiles from database (supports limit & offset) |
| API to fetch data of a single profile | GET /api/v1/profiles/:username — returns one stored record by GitHub login |
Required insights stored (examples):
| Insight | Stored as |
|---|---|
| Public repository count | public_repo_count |
| Followers count | followers_count |
| Following count | following_count |
| Total stars / forks | total_stars, total_forks |
| Top languages | top_languages (JSON) |
| Most starred repo | most_starred_repo (JSON) |
| Account age | account_age_days, account_created_at |
Features added per "Add any improvements/features you think would make the project better":
| # | Feature | Endpoint / detail |
|---|---|---|
| 1 | Contributions analytics | Last year, month, week totals (GitHub GraphQL) |
| 2 | Longest contribution streak | insights.contributions.longest_streak_days |
| 3 | Commits count | insights.contributions.commits_count |
| 4 | Recent repos (top 5) | insights.recent_repos_top_5 |
| 5 | Compare two profiles | GET /api/v1/profiles/compare?user1=&user2= |
| 6 | Search GitHub users | GET /api/v1/search/users?q= |
| 7 | Health check | GET /api/v1/health — API + MySQL status |
| 8 | Pagination | GET /profiles?limit=&offset= |
| 9 | Upsert on re-analyze | Same username updates row (no duplicates) |
| 10 | API versioning | All routes under /api/v1 |
| 11 | Structured errors | Consistent { success, error, code } responses |
| 12 | Pretty JSON | Readable indented API responses |
| 13 | Docker Compose | Local MySQL for development |
| 14 | Dual GitHub APIs | REST + GraphQL for richer insights |
| 15 | Production deploy | Render (API) + Railway (MySQL) |
| 16 | Export Profile | GET /api/v1/profiles/:username/export?format=csv |
Columns: username, display name, bio, avatar, location, company, blog, followers, following, public repos, stars, forks, languages, most starred repo, account age, last activity.
insights JSON: GitHub ID, contributions breakdown, longest streak, commits count, recent_repos_top_5, averages.
Full field list: schema.sql
Production base URL: https://midaksh-github-analyzer-api.onrender.com
| Method | Path | Description |
|---|---|---|
GET |
/ |
Service metadata and route index |
GET |
/api/v1/health |
Liveness and database check |
POST |
/api/v1/profiles/analyze |
Analyze and persist { "username": "..." } |
GET |
/api/v1/profiles |
List stored profiles |
GET |
/api/v1/profiles/:username |
Fetch one profile |
GET |
/api/v1/profiles/compare |
Compare two profiles (user1, user2) |
GET |
/api/v1/search/users |
Search GitHub users (q, per_page, page) |
# Health
curl https://midaksh-github-analyzer-api.onrender.com/api/v1/health
# Analyze
curl -X POST https://midaksh-github-analyzer-api.onrender.com/api/v1/profiles/analyze \
-H "Content-Type: application/json" \
-d '{"username":"midaksh"}'
# Compare (both profiles must exist in database)
curl "https://midaksh-github-analyzer-api.onrender.com/api/v1/profiles/compare?user1=midaksh&user2=octocat"
# Search
curl "https://midaksh-github-analyzer-api.onrender.com/api/v1/search/users?q=midaksh"Browser-friendly (GET): /api/v1/health, /api/v1/profiles, /api/v1/profiles/{username}, /api/v1/profiles/compare, /api/v1/search/users.
Requirements: Node.js 18+ - Docker - GitHub Personal Access Token
git clone https://github.com/midaksh/github-analyzer-api.git
cd github-analyzer-api
npm install
docker compose up -d
cp .env.example .env
# Configure GITHUB_TOKEN and database credentials in .env
npm run db:migrate
npm run devConfirm: http://localhost:5004/api/v1/health → "database": "connected"
| Step | Command |
|---|---|
| Install dependencies | npm install |
| Start local MySQL | docker compose up -d |
| Apply schema | npm run db:migrate |
| Run development server | npm run dev |
| Run production server | npm start |
| Variable | Required | Description |
|---|---|---|
GITHUB_TOKEN |
Yes | Authenticates REST and GraphQL requests; raises rate limits |
PORT |
No | HTTP port (default 5004) |
NODE_ENV |
No | development or production |
GITHUB_API_VERSION |
No | Default 2026-03-10 |
DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME |
Local | Individual MySQL settings |
DATABASE_URL |
Cloud | Full connection string (preferred on Render) |
Use either DB_* (local) or DATABASE_URL (production). Never commit .env.
| Service | Platform | Notes |
|---|---|---|
| API | Render | Web Service, Node runtime |
| Database | Railway | MySQL; expose public URL only |
Build Command: npm install
Start Command: npm run db:migrate && npm start
| Environment variable | Value |
|---|---|
DATABASE_URL |
Railway MYSQL_PUBLIC_URL (not mysql.railway.internal) |
GITHUB_TOKEN |
GitHub PAT |
NODE_ENV |
production |
Extended setup and architecture notes: Project documentation (Notion).
| Resource | Location |
|---|---|
| Database schema | schema.sql |
| Postman collection | postman/github-profile-analyzer.postman_collection.json |
| Environment template | .env.example |
Node.js · Express.js · MySQL · mysql2 · GitHub REST API · GitHub GraphQL API · Zod · Docker Compose