Here’s a walkthrough of my experience building the “Dynamic Profile Endpoint” (GET /me) for the HNG Internship Stage 0 task — using TypeScript, Express, and integrating with the Cat Facts API.
The Core Objective: Dynamic Profile Endpoint
The primary goal was to create a single endpoint that returns static profile data combined with real-time, dynamic data fetched from a third-party service.
Key goals:
- Use TypeScript to have typed safety and clearer code.
- Use Express for the HTTP server.
- Add security (helmet), CORS, logging, rate-limiting.
- Clean separation: routes, controller, middleware, error handler.
Fetch a live fact (from cat fact api when serving the /me endpoint.
Provide a well‑structured JSON response including status, user info, timestamp, fact.
Endpoint Requirements:
-
Method:
GET
-
URL:
/me
-
Response: A JSON object containing static user details (name, email, stack), timestamp to show current time the request was made and a dynamic field (
fact
) fetched from The Cat Facts API. -
Success Status:
HTTP/1.1 200 OK
.
🧠 What I Built
The task required building an HTTP GET /me
endpoint that returns:
- My profile (name, email, stack)
- A dynamic cat fact (from CatFact Ninja)
- A timestamp of the request
- A consistent JSON response structure
To meet these requirements, I used:
- TypeScript: for static typing and better developer experience
-
Express.js: for building the get
/me
endpoint - Axios: for HTTP requests to the Cat Facts API
- Helmet & CORS: to secure HTTP headers and allow cross-origin requests
- Rate limiting middleware: to prevent abuse
- Custom error & logging middleware
🗂 Project Structure
├── controllers/
│ └── profile.controller.ts # Business logic for the /me endpoint
├── middlewares/
│ ├── errorHandler.ts # Global error handling middleware
│ ├── logging.ts # Logging middleware
│ └── rate-limiting.ts # Rate limiting middleware
├── routes/
│ └── profile.routes.ts # Defines the GET /me endpoint
├── types/
│ └── profile.ts # TypeScript interfaces and types
├── utils/
│ └── apiError.ts # Custom reusable error class
├── .env # Environment variables
├── index.ts # Main application entry point
├── package.json
└── tsconfig.json
⚙️ Setup & Running Locally
1. Clone the Repository
git clone https://github.com/ideateGudy/Dynamic-Profile-Endpoint.git
cd Dynamic-Profile-Endpoint
2. Install Dependencies
npm install
3. Create .env File
In the root directory, create a .env file and add the following:
PORT=3000
NODE_ENV=development
CATFACT_BASE_URL=https://catfact.ninja
4. Start the Server
Development mode (auto-restart with file changes):
npm run dev
Production build:
npm run build
Run compiled JS:
npm start
Once the server starts, access it via:
http://localhost:3000
🧪 Testing the /me
Endpoint
Sample Response
{
"status": "success",
"user": {
"email": "azonubigoodnews@gmail.com",
"name": "Goodnews Azonubi",
"stack": "Nodejs/Express/Typescript"
},
"timestamp": "2025-10-18T10:43:33.791Z",
"fact": "A tiger’s stripes are like fingerprints"
}
🔍 Behind the Scenes: How It Works
-
GET /me
Route
Located in: routes/profile.routes.ts
It calls a service function that:
- Defines static profile data
- Pulls a cat fact via axios
- Adds an ISO timestamp
- Returns the combined response
- Cat Facts API
API used: https://catfact.ninja/fact
Response format:
{
"fact": "Cats sleep for 70% of their lives.",
"length": 38
}
- Middlewares
helmet: Secures HTTP headers
cors: Enables basic cross-origin requests
rate-limiting: Prevents request abuse
logging: Logs method, path, response time
errorHandler: Catches and handles server errors
📚 What I Learned
Rate Limiting: Added protection against spamming endpoints using express-rate-limit
Middleware Layers: Execution order matters — I learned to carefully apply middlewares in the correct sequence
Structured Error Handling: Centralized error catching and response formatting
Project Structure: Separated routing, controller, and middleware for maintainability
🚀 Github repo
Please refer to the full repository for the complete code
Dynamic-Profile-Endpoint Github Repo
Top comments (0)