Notes

8 notes
README.md
# README.md

Ammar Bin Shakir

Building systems that scale.
React·Node.js·AWS·TypeScript· Pakistan

I build resilient, scalable web systems — from database schemas to polished UIs. Passionate about clean architecture, AWS, and the craft of engineering.

## about

👋 Hey! I'm Ammar Bin Shakir, a fullstack engineer experienced in React, Node.js, Next.js, React Native, and AWS. I specialize in building dynamic web and mobile applications with a strong emphasis on scalability, security, and performance.

# skills.md
3 skills
LANGUAGES(3)
JavaScript
TypeScript
Python
# experience.md

Senior Software Engineer

@ Pixelpk Technologies

Leading full-stack development projects using modern technologies. Architected scalable solutions and mentored junior developers.

ReactNode.jsTypeScriptAWSMongoDBGraphQL
Jan 2023 - Present

Senior Web Engineer

@ Geekinate

Developed high-performance web applications and implemented CI/CD pipelines. Improved application performance by 40%.

Next.jsReactNode.jsPostgreSQLDockerKubernetes
May 2022 - Dec 2022

MERN Stack Developer

@ SAS Technology

Built responsive web applications and RESTful APIs. Collaborated with cross-functional teams to deliver client solutions.

MongoDBExpress.jsReactNode.jsReduxMaterial-UI
Apr 2021 - Apr 2022

MERN Stack Developer

@ Cipher Savvy

Developed and maintained web applications using MERN stack. Focused on creating user-friendly interfaces and robust backend systems.

ReactNode.jsMongoDBExpress.jsJavaScriptBootstrap
Sep 2020 - Mar 2021

Web Development Intern

@ Seven Technologies

Gained hands-on experience in web development fundamentals. Contributed to various client projects and learned industry best practices.

HTMLCSSJavaScriptPHPMySQLjQuery
Feb 2020 - Apr 2020
## CERTIFICATIONS (4)
AWS Educate Introduction to Cloud 101
AWS · June 2025
Cloud ComputingAWS FundamentalsCloud ArchitectureInfrastructure
LangChain for LLM Application Development
deeplearning.ai · June 2025
LangChainLLM DevelopmentAI ApplicationsPython
ChatGPT Prompt Engineering for Developers
deeplearning.ai · June 2025
Prompt EngineeringChatGPTAI IntegrationDeveloper Tools
Reasoning with OpenAI o1 Model
deeplearning.ai · June 2025
OpenAI o1Advanced ReasoningAI Problem SolvingModel Optimization
# projects.md
PROJECTS (8)

Diazo - Food Delivery Service

visit

A web application for a fast-food chain, offering menu selection, order tracking, and Google Maps integration, using Firebase for efficient service.

TECH STACK
ReactFirebaseFirebase AuthFiebase databaseFirebase Cloud FunctionsGoogle Maps APIMaterial-UIStripeNode JS
PROJECTS (8)

A web application for a fast-food chain, offering menu selection, order tracking, and Google Maps integration, using Firebase for efficient service.

visit
ReactFirebaseFirebase AuthFiebase databaseFirebase Cloud FunctionsGoogle Maps APIMaterial-UIStripeNode JS
# writing.md

Kubernetes for Full-Stack Developers: A Gentle Introduction

What I learned transitioning from Docker Compose to Kubernetes, one manifest at a time. As a full-stack developer who’s spent most of his time building with React, Node.js, PostgreSQL, and Redis, Kubernetes always felt like something that belonged in the world of DevOps engineers or SREs. I used Docker Compose to spin up local dev environments, wrote decent CI pipelines, and deployed apps to Heroku or Vercel. That worked — until it didn’t. When I started working on a URL shortener project that needed scalable infrastructure and fine-grained container control, I decided it was time to get serious about Kubernetes. This post reflects my beginner journey — no buzzwords, no jargon — just the practical lessons I learned while containerizing and deploying a full-stack app using Kubernetes. 🧩 What is Kubernetes, really? In simple terms, Kubernetes (K8s) is a system that helps you run and manage containers (like your Docker apps) at scale. It handles things like auto-restarting crashed apps, distributing traffic, storing persistent data, and more — across clusters of machines. Think of it as Docker Compose on steroids — but with a learning curve. 🙋‍♂️ New to Kubernetes? Don’t worry if the YAML looks scary. It did for me too. Stick with it — the core ideas will click. 🧠 Why I Decided to Learn Kubernetes I was building a URL shortener app with the following stack: Node.js API (Express) — handles shortening and redirection PostgreSQL — stores the URLs Redis — caches popular URLs for performance 📦 Want to follow along? The complete source code and Kubernetes manifests are available on GitHub Docker Compose worked fine locally, but I knew it wouldn’t scale or survive container crashes in production. I wanted: Resilience (auto-restart, auto-healing) Environment parity (dev, staging, prod) Persistent storage Secure environment variable management Built-in service discovery Kubernetes offered all of this and more — but the learning curve was steep. 🧱 Writing My First Deployment YAML I started with a simple goal: run my Node.js API in Kubernetes. Here’s a minimal Deployment and Service manifest: apiVersion: apps/v1 kind: Deployment metadata: name: url-shortener-api spec: replicas: 2 selector: matchLabels: app: url-shortener template: metadata: labels: app: url-shortener spec: containers: - name: api image: ammarbinshakir/url-shortener:latest ports: - containerPort: 3000 --- apiVersion: v1 kind: Service metadata: name: url-shortener-service spec: selector: app: url-shortener ports: - port: 80 targetPort: 3000 type: ClusterIP Why 2 replicas? So I could test load balancing and see how Kubernetes handled pod scaling and restarts. Takeaway: Kubernetes is declarative. You define the desired state, and it ensures the cluster converges toward that. 💾 Persisting PostgreSQL with Volumes Next, I added PostgreSQL — but hit my first real problem: Every time the Postgres pod restarted, the data vanished. Unlike Docker Compose, Kubernetes doesn’t automatically persist container data. I had to define a PersistentVolumeClaim (PVC): apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi And then mount it inside the deployment: volumeMounts: - mountPath: /var/lib/postgresql/data name: postgres-storage volumes: - name: postgres-storage persistentVolumeClaim: claimName: postgres-pvc 🔍 ReadWriteOnce means the volume can be mounted as read-write by a single node. I also needed a Service to expose Postgres internally: apiVersion: v1 kind: Service metadata: name: postgres-service spec: selector: app: postgres ports: - port: 5432 targetPort: 5432 type: ClusterIP Lesson learned: Stateful apps need persistent volumes, or your data is toast. 🔁 Understanding StatefulSets Initially, I ran both PostgreSQL and Redis using Deployments. It worked — until I realized that pods were being replaced with new names/IPs during scaling or restarts, which broke the connection logic. This is where StatefulSets come in. StatefulSets assign stable DNS and identities to pods (redis-0, redis-1, etc.). This is crucial for services like Redis or Postgres that expect consistency in hostnames or storage. After switching Redis to aStatefulSet, my caching layer stopped randomly failing on restarts. 🔐 Managing Secrets and Configs Coming from .env files, I wondered: How does Kubernetes handle secrets? Kubernetes has: ConfigMaps — for non-sensitive config like feature flags or API endpoints. Secrets — for sensitive data like DB passwords and tokens. Example: apiVersion: v1 kind: Secret metadata: name: db-secret type: Opaque data: POSTGRES_PASSWORD: c3VwZXJzZWNyZXQ= # base64 encoded Injecting the secret into the container: env: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: db-secret key: POSTGRES_PASSWORD You can also mount secrets as files if needed. ⏱ Boot Order and Service Dependencies A common frustration: my API would start before Postgres was ready. There’s no depends_on in Kubernetes, like in Docker Compose. I solved this using: readinessProbes to mark the Postgres pod as “ready” only when it accepts connections. initContainers In the API pod to wait for Postgres before starting the main app. Example readinessProbe for Postgres: readinessProbe: exec: command: - pg_isready initialDelaySeconds: 5 periodSeconds: 10 This approach ensured that my services came online in the right order — and stayed that way. 🧪 Local Testing with Minikube To test everything locally, I used: Minikube — the easiest way to spin up a local K8s cluster kubectl — essential CLI tool for interacting with the cluster Once you get the hang of kubectl apply -fKubernetes starts to feel manageable. 📚 Lessons Learned Here are a few takeaways from my first real Kubernetes experience: ✅ YAML fatigue is real, but you can reduce repetition using Helm or Kustomize ✅ StatefulSets are a must for databases and caching services ✅ Debugging is different — rely on kubectl logs, describe, and exec ✅ Start small — don’t jump straight to Ingress, autoscaling, or Helm ✅ Kubernetes doesn’t replace Docker — it orchestrates it ✅ Embrace the declarative mindset — it's a shift, but worth it 🔗 Resources That Helped Me 📘 Kubernetes Official Docs 🧪 Play with Kubernetes 📚 Kelsey Hightower’s Kubernetes the Hard Way 🎨 Learnk8s Visual Guides 🧠 Final Thoughts Learning Kubernetes as a full-stack developer may seem intimidating — but it’s one of the most powerful tools you can add to your engineering toolkit. You don’t need to master everything on day one. Start with the basics: Deployments, Services, Volumes, Secrets. Build something real. Break it. Fix it. Learn by doing. Most developers stop at Docker Compose. If you go even one step beyond that — you’re ahead of the curve. 🚀 Up Next: In the next post, I’ll walk through how I deployed this app with Ingress, TLS, and autoscaling on a cloud cluster. 📬 Follow me here on Medium, or connect with me on LinkedIn | Portfolio
read on Medium
Aug 7, 2025

Implementing Server-Sent Events (SSE) in Node.js with Next.js: A Complete Guide

Server-Sent Events (SSE) offer a simple way to stream real-time updates from the server to the client, ideal for use cases like live notifications or dashboards. This guide walks you through implementing SSE with a Node.js backend and a Next.js client, enabling a modern, efficient solution for real-time data streaming. 1. Setting Up the SSE Server in Node.js Create a simple Node.js SSE server (same as before): const express = require('express'); const app = express(); const PORT = 3000; app.get('/events', (req, res) => { // Set SSE headers res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); // Initial message res.write('data: Welcome to Server-Sent Events!\n\n'); // Send messages every 5 seconds const intervalId = setInterval(() => { const message = { time: new Date().toISOString() }; res.write(`data: ${JSON.stringify(message)}\n\n`); }, 5000); // Clean up on disconnect req.on('close', () => { clearInterval(intervalId); res.end(); }); }); app.listen(PORT, () => { console.log(`SSE server running on http://localhost:${PORT}`); }); 2. Setting Up the Next.js Client Step 1: Initialize a Next.js Project Create a new Next.js project: npx create-next-app@latest sse-nextjs cd sse-nextjs Start the development server: npm run dev Step 2: Create a Page for SSE in Next.js Create a new file in the pages directory, e.g., pages/sse.js. Add the following code to consume the SSE stream: import { useState, useEffect } from 'react'; export default function SSEPage() { const [messages, setMessages] = useState([]); useEffect(() => { // Create an EventSource to listen to SSE events const eventSource = new EventSource('http://localhost:3000/events'); // Handle incoming messages eventSource.onmessage = (event) => { const data = JSON.parse(event.data); setMessages((prevMessages) => [...prevMessages, data]); }; // Handle errors eventSource.onerror = () => { console.error('Error connecting to SSE server.'); eventSource.close(); }; // Cleanup on unmount return () => { eventSource.close(); }; }, []); return (

Server-Sent Events (SSE) with Next.js

{messages.map((message, index) => (

Message received at: {message.time}

))}
); } Step 3: Add Navigation (Optional) Update the pages/index.js file to include a link to the SSE page: import Link from 'next/link'; export default function Home() { return (

Welcome to Next.js SSE Example

Go to SSE Page
); } 3. Running the Application Start the Node.js SSE server: node server.js Run the Next.js development server: npm run dev Open your browser and visit http://localhost:3000/sse to see the live SSE updates. How This Works EventSource in React: The EventSource API listens to the SSE stream provided by the Node.js server. State Management: Incoming messages are appended to the messages state array using React's useState and useEffect. Real-Time UI Updates: React automatically re-renders the UI whenever the messages state changes. Conclusion Server-Sent Events (SSE) offers a lightweight, easy-to-implement solution for real-time data streaming from the server to the client. While it’s not as versatile as WebSockets, SSE is perfect for scenarios where only server-to-client communication is needed. With its simplicity and browser-native support, SSE can be a great addition to your toolkit for building dynamic and engaging web applications. If you enjoyed this tutorial, let me know in the comments or share your experience with SSE! Happy coding! 🚀
read on Medium
Dec 21, 2024

WhatsApp API Integration with Node.js

WhatsApp is one of the most widely used messaging platforms globally, and integrating it with your applications can enhance communication with your users. Meta (formerly Facebook) offers a Cloud API for WhatsApp that allows developers to send and receive messages programmatically. In this blog, we’ll walk through the steps to integrate the Meta Cloud WhatsApp API with a Node.js application. Step 1: Set Up a Node.js Project First, create a new Node.js project and install the necessary dependencies. mkdir whatsapp-nodejs cd whatsapp-nodejs npm init -y npm install express axios body-parser Step 2: Create a Basic Express Server Create a file named server.js and set up a basic Express server. const express = require('express'); const axios = require('axios'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); }); Step 3: Configure Environment Variables Create a .env file to store your API credentials. WHATSAPP_API_URL=https://graph.facebook.com/v13.0/YOUR_PHONE_NUMBER_ID/messages ACCESS_TOKEN=YOUR_ACCESS_TOKEN Load these variables in your server.js file using the dotenv package. npm install dotenv Update server.js to include dotenv. require('dotenv').config(); const WHATSAPP_API_URL = process.env.WHATSAPP_API_URL; const ACCESS_TOKEN = process.env.ACCESS_TOKEN; Step 4: Implement Sending Messages Add an endpoint to send WhatsApp messages. app.post('/send-message', async (req, res) => { const { phoneNumber, message } = req.body; try { const response = await axios.post( WHATSAPP_API_URL, { messaging_product: 'whatsapp', to: phoneNumber, text: { body: message } }, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${ACCESS_TOKEN}` } } ); res.status(200).json({ success: true, data: response.data }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); Step 5: Implement Receiving Messages To receive messages, you need to set up a webhook. First, create an endpoint to handle incoming messages. app.post('/webhook', (req, res) => { const data = req.body; console.log('Webhook received:', data); // Handle the incoming message here res.sendStatus(200); }); Configure your webhook URL in the Meta Developer Portal. If you’re developing locally, use ngrok to expose your localhost. ngrok http 3000 Use the ngrok URL in the Meta Developer Portal for the webhook configuration. Step 6: Verify the Webhook Meta requires webhook verification. Add an endpoint for verification. app.get('/webhook', (req, res) => { const VERIFY_TOKEN = 'your-verify-token'; const mode = req.query['hub.mode']; const token = req.query['hub.verify_token']; const challenge = req.query['hub.challenge']; if (mode && token === VERIFY_TOKEN) { res.status(200).send(challenge); } else { res.sendStatus(403); } }); Step 7: Test Your Integration Start your server and test sending and receiving messages. node server.js Use Postman or a similar tool to send a POST request to http://localhost:3000/send-message with the following JSON body: { "phoneNumber": "whatsapp:+1234567890", "message": "Hello from Node.js!" } Conclusion Integrating the Meta Cloud WhatsApp API with Node.js allows you to leverage the power of WhatsApp for your applications. Following these steps, you can set up a basic integration to send and receive messages. Explore the API documentation further to unlock more features and capabilities for your applications. #NodeJS #WhatsAppAPI #MetaAPI #WebDevelopment #JavaScript #MessagingApp #CloudAPI #ExpressJS #FullStackDevelopment #APIntegration #Coding #SoftwareDevelopment #TechBlog https://developers.facebook.com/docs/whatsapp/cloud-api/
read on Medium
Jul 20, 2024
# contact.md

Building something interesting?
Let's talk.

built withNext.js · Tailwind · Vercel
# README.md

React·Node.js·Next.js·AWS·TypeScript· Pakistan

I build resilient, scalable web systems — from database schemas to polished UIs. Passionate about clean architecture, AWS, and the craft of engineering.

# about.md

About

👋 Hey there! I'm Ammar Bin Shakir, a fullstack engineer experienced in React, Node.js, Next.js, React Native, and AWS services. I specialize in building dynamic web and mobile applications with a strong emphasis on utilizing AWS to enhance scalability, security, and overall performance.

# skills.md

Skills & Technologies

3 skills
LANGUAGES(3)
JavaScript
TypeScript
Python
# experience.md

Experience

Senior Software Engineer

@ Pixelpk Technologies

Leading full-stack development projects using modern technologies. Architected scalable solutions and mentored junior developers.

ReactNode.jsTypeScriptAWSMongoDBGraphQL
Jan 2023 - Present

Senior Web Engineer

@ Geekinate

Developed high-performance web applications and implemented CI/CD pipelines. Improved application performance by 40%.

Next.jsReactNode.jsPostgreSQLDockerKubernetes
May 2022 - Dec 2022

MERN Stack Developer

@ SAS Technology

Built responsive web applications and RESTful APIs. Collaborated with cross-functional teams to deliver client solutions.

MongoDBExpress.jsReactNode.jsReduxMaterial-UI
Apr 2021 - Apr 2022

MERN Stack Developer

@ Cipher Savvy

Developed and maintained web applications using MERN stack. Focused on creating user-friendly interfaces and robust backend systems.

ReactNode.jsMongoDBExpress.jsJavaScriptBootstrap
Sep 2020 - Mar 2021

Web Development Intern

@ Seven Technologies

Gained hands-on experience in web development fundamentals. Contributed to various client projects and learned industry best practices.

HTMLCSSJavaScriptPHPMySQLjQuery
Feb 2020 - Apr 2020
## CERTIFICATIONS (4)
AWS Educate Introduction to Cloud 101
AWS · June 2025
Cloud ComputingAWS FundamentalsCloud ArchitectureInfrastructure
LangChain for LLM Application Development
deeplearning.ai · June 2025
LangChainLLM DevelopmentAI ApplicationsPython
ChatGPT Prompt Engineering for Developers
deeplearning.ai · June 2025
Prompt EngineeringChatGPTAI IntegrationDeveloper Tools
Reasoning with OpenAI o1 Model
deeplearning.ai · June 2025
OpenAI o1Advanced ReasoningAI Problem SolvingModel Optimization
# projects.md

Projects

PROJECTS (8)

Diazo - Food Delivery Service

visit

A web application for a fast-food chain, offering menu selection, order tracking, and Google Maps integration, using Firebase for efficient service.

TECH STACK
ReactFirebaseFirebase AuthFiebase databaseFirebase Cloud FunctionsGoogle Maps APIMaterial-UIStripeNode JS
PROJECTS (8)

A web application for a fast-food chain, offering menu selection, order tracking, and Google Maps integration, using Firebase for efficient service.

visit
ReactFirebaseFirebase AuthFiebase databaseFirebase Cloud FunctionsGoogle Maps APIMaterial-UIStripeNode JS
# writing.md

Writing

Kubernetes for Full-Stack Developers: A Gentle Introduction

What I learned transitioning from Docker Compose to Kubernetes, one manifest at a time. As a full-stack developer who’s spent most of his time building with React, Node.js, PostgreSQL, and Redis, Kubernetes always felt like something that belonged in the world of DevOps engineers or SREs. I used Docker Compose to spin up local dev environments, wrote decent CI pipelines, and deployed apps to Heroku or Vercel. That worked — until it didn’t. When I started working on a URL shortener project that needed scalable infrastructure and fine-grained container control, I decided it was time to get serious about Kubernetes. This post reflects my beginner journey — no buzzwords, no jargon — just the practical lessons I learned while containerizing and deploying a full-stack app using Kubernetes. 🧩 What is Kubernetes, really? In simple terms, Kubernetes (K8s) is a system that helps you run and manage containers (like your Docker apps) at scale. It handles things like auto-restarting crashed apps, distributing traffic, storing persistent data, and more — across clusters of machines. Think of it as Docker Compose on steroids — but with a learning curve. 🙋‍♂️ New to Kubernetes? Don’t worry if the YAML looks scary. It did for me too. Stick with it — the core ideas will click. 🧠 Why I Decided to Learn Kubernetes I was building a URL shortener app with the following stack: Node.js API (Express) — handles shortening and redirection PostgreSQL — stores the URLs Redis — caches popular URLs for performance 📦 Want to follow along? The complete source code and Kubernetes manifests are available on GitHub Docker Compose worked fine locally, but I knew it wouldn’t scale or survive container crashes in production. I wanted: Resilience (auto-restart, auto-healing) Environment parity (dev, staging, prod) Persistent storage Secure environment variable management Built-in service discovery Kubernetes offered all of this and more — but the learning curve was steep. 🧱 Writing My First Deployment YAML I started with a simple goal: run my Node.js API in Kubernetes. Here’s a minimal Deployment and Service manifest: apiVersion: apps/v1 kind: Deployment metadata: name: url-shortener-api spec: replicas: 2 selector: matchLabels: app: url-shortener template: metadata: labels: app: url-shortener spec: containers: - name: api image: ammarbinshakir/url-shortener:latest ports: - containerPort: 3000 --- apiVersion: v1 kind: Service metadata: name: url-shortener-service spec: selector: app: url-shortener ports: - port: 80 targetPort: 3000 type: ClusterIP Why 2 replicas? So I could test load balancing and see how Kubernetes handled pod scaling and restarts. Takeaway: Kubernetes is declarative. You define the desired state, and it ensures the cluster converges toward that. 💾 Persisting PostgreSQL with Volumes Next, I added PostgreSQL — but hit my first real problem: Every time the Postgres pod restarted, the data vanished. Unlike Docker Compose, Kubernetes doesn’t automatically persist container data. I had to define a PersistentVolumeClaim (PVC): apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi And then mount it inside the deployment: volumeMounts: - mountPath: /var/lib/postgresql/data name: postgres-storage volumes: - name: postgres-storage persistentVolumeClaim: claimName: postgres-pvc 🔍 ReadWriteOnce means the volume can be mounted as read-write by a single node. I also needed a Service to expose Postgres internally: apiVersion: v1 kind: Service metadata: name: postgres-service spec: selector: app: postgres ports: - port: 5432 targetPort: 5432 type: ClusterIP Lesson learned: Stateful apps need persistent volumes, or your data is toast. 🔁 Understanding StatefulSets Initially, I ran both PostgreSQL and Redis using Deployments. It worked — until I realized that pods were being replaced with new names/IPs during scaling or restarts, which broke the connection logic. This is where StatefulSets come in. StatefulSets assign stable DNS and identities to pods (redis-0, redis-1, etc.). This is crucial for services like Redis or Postgres that expect consistency in hostnames or storage. After switching Redis to aStatefulSet, my caching layer stopped randomly failing on restarts. 🔐 Managing Secrets and Configs Coming from .env files, I wondered: How does Kubernetes handle secrets? Kubernetes has: ConfigMaps — for non-sensitive config like feature flags or API endpoints. Secrets — for sensitive data like DB passwords and tokens. Example: apiVersion: v1 kind: Secret metadata: name: db-secret type: Opaque data: POSTGRES_PASSWORD: c3VwZXJzZWNyZXQ= # base64 encoded Injecting the secret into the container: env: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: db-secret key: POSTGRES_PASSWORD You can also mount secrets as files if needed. ⏱ Boot Order and Service Dependencies A common frustration: my API would start before Postgres was ready. There’s no depends_on in Kubernetes, like in Docker Compose. I solved this using: readinessProbes to mark the Postgres pod as “ready” only when it accepts connections. initContainers In the API pod to wait for Postgres before starting the main app. Example readinessProbe for Postgres: readinessProbe: exec: command: - pg_isready initialDelaySeconds: 5 periodSeconds: 10 This approach ensured that my services came online in the right order — and stayed that way. 🧪 Local Testing with Minikube To test everything locally, I used: Minikube — the easiest way to spin up a local K8s cluster kubectl — essential CLI tool for interacting with the cluster Once you get the hang of kubectl apply -fKubernetes starts to feel manageable. 📚 Lessons Learned Here are a few takeaways from my first real Kubernetes experience: ✅ YAML fatigue is real, but you can reduce repetition using Helm or Kustomize ✅ StatefulSets are a must for databases and caching services ✅ Debugging is different — rely on kubectl logs, describe, and exec ✅ Start small — don’t jump straight to Ingress, autoscaling, or Helm ✅ Kubernetes doesn’t replace Docker — it orchestrates it ✅ Embrace the declarative mindset — it's a shift, but worth it 🔗 Resources That Helped Me 📘 Kubernetes Official Docs 🧪 Play with Kubernetes 📚 Kelsey Hightower’s Kubernetes the Hard Way 🎨 Learnk8s Visual Guides 🧠 Final Thoughts Learning Kubernetes as a full-stack developer may seem intimidating — but it’s one of the most powerful tools you can add to your engineering toolkit. You don’t need to master everything on day one. Start with the basics: Deployments, Services, Volumes, Secrets. Build something real. Break it. Fix it. Learn by doing. Most developers stop at Docker Compose. If you go even one step beyond that — you’re ahead of the curve. 🚀 Up Next: In the next post, I’ll walk through how I deployed this app with Ingress, TLS, and autoscaling on a cloud cluster. 📬 Follow me here on Medium, or connect with me on LinkedIn | Portfolio
read on Medium
Aug 7, 2025

Implementing Server-Sent Events (SSE) in Node.js with Next.js: A Complete Guide

Server-Sent Events (SSE) offer a simple way to stream real-time updates from the server to the client, ideal for use cases like live notifications or dashboards. This guide walks you through implementing SSE with a Node.js backend and a Next.js client, enabling a modern, efficient solution for real-time data streaming. 1. Setting Up the SSE Server in Node.js Create a simple Node.js SSE server (same as before): const express = require('express'); const app = express(); const PORT = 3000; app.get('/events', (req, res) => { // Set SSE headers res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); // Initial message res.write('data: Welcome to Server-Sent Events!\n\n'); // Send messages every 5 seconds const intervalId = setInterval(() => { const message = { time: new Date().toISOString() }; res.write(`data: ${JSON.stringify(message)}\n\n`); }, 5000); // Clean up on disconnect req.on('close', () => { clearInterval(intervalId); res.end(); }); }); app.listen(PORT, () => { console.log(`SSE server running on http://localhost:${PORT}`); }); 2. Setting Up the Next.js Client Step 1: Initialize a Next.js Project Create a new Next.js project: npx create-next-app@latest sse-nextjs cd sse-nextjs Start the development server: npm run dev Step 2: Create a Page for SSE in Next.js Create a new file in the pages directory, e.g., pages/sse.js. Add the following code to consume the SSE stream: import { useState, useEffect } from 'react'; export default function SSEPage() { const [messages, setMessages] = useState([]); useEffect(() => { // Create an EventSource to listen to SSE events const eventSource = new EventSource('http://localhost:3000/events'); // Handle incoming messages eventSource.onmessage = (event) => { const data = JSON.parse(event.data); setMessages((prevMessages) => [...prevMessages, data]); }; // Handle errors eventSource.onerror = () => { console.error('Error connecting to SSE server.'); eventSource.close(); }; // Cleanup on unmount return () => { eventSource.close(); }; }, []); return (

Server-Sent Events (SSE) with Next.js

{messages.map((message, index) => (

Message received at: {message.time}

))}
); } Step 3: Add Navigation (Optional) Update the pages/index.js file to include a link to the SSE page: import Link from 'next/link'; export default function Home() { return (

Welcome to Next.js SSE Example

Go to SSE Page
); } 3. Running the Application Start the Node.js SSE server: node server.js Run the Next.js development server: npm run dev Open your browser and visit http://localhost:3000/sse to see the live SSE updates. How This Works EventSource in React: The EventSource API listens to the SSE stream provided by the Node.js server. State Management: Incoming messages are appended to the messages state array using React's useState and useEffect. Real-Time UI Updates: React automatically re-renders the UI whenever the messages state changes. Conclusion Server-Sent Events (SSE) offers a lightweight, easy-to-implement solution for real-time data streaming from the server to the client. While it’s not as versatile as WebSockets, SSE is perfect for scenarios where only server-to-client communication is needed. With its simplicity and browser-native support, SSE can be a great addition to your toolkit for building dynamic and engaging web applications. If you enjoyed this tutorial, let me know in the comments or share your experience with SSE! Happy coding! 🚀
read on Medium
Dec 21, 2024

WhatsApp API Integration with Node.js

WhatsApp is one of the most widely used messaging platforms globally, and integrating it with your applications can enhance communication with your users. Meta (formerly Facebook) offers a Cloud API for WhatsApp that allows developers to send and receive messages programmatically. In this blog, we’ll walk through the steps to integrate the Meta Cloud WhatsApp API with a Node.js application. Step 1: Set Up a Node.js Project First, create a new Node.js project and install the necessary dependencies. mkdir whatsapp-nodejs cd whatsapp-nodejs npm init -y npm install express axios body-parser Step 2: Create a Basic Express Server Create a file named server.js and set up a basic Express server. const express = require('express'); const axios = require('axios'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); }); Step 3: Configure Environment Variables Create a .env file to store your API credentials. WHATSAPP_API_URL=https://graph.facebook.com/v13.0/YOUR_PHONE_NUMBER_ID/messages ACCESS_TOKEN=YOUR_ACCESS_TOKEN Load these variables in your server.js file using the dotenv package. npm install dotenv Update server.js to include dotenv. require('dotenv').config(); const WHATSAPP_API_URL = process.env.WHATSAPP_API_URL; const ACCESS_TOKEN = process.env.ACCESS_TOKEN; Step 4: Implement Sending Messages Add an endpoint to send WhatsApp messages. app.post('/send-message', async (req, res) => { const { phoneNumber, message } = req.body; try { const response = await axios.post( WHATSAPP_API_URL, { messaging_product: 'whatsapp', to: phoneNumber, text: { body: message } }, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${ACCESS_TOKEN}` } } ); res.status(200).json({ success: true, data: response.data }); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); Step 5: Implement Receiving Messages To receive messages, you need to set up a webhook. First, create an endpoint to handle incoming messages. app.post('/webhook', (req, res) => { const data = req.body; console.log('Webhook received:', data); // Handle the incoming message here res.sendStatus(200); }); Configure your webhook URL in the Meta Developer Portal. If you’re developing locally, use ngrok to expose your localhost. ngrok http 3000 Use the ngrok URL in the Meta Developer Portal for the webhook configuration. Step 6: Verify the Webhook Meta requires webhook verification. Add an endpoint for verification. app.get('/webhook', (req, res) => { const VERIFY_TOKEN = 'your-verify-token'; const mode = req.query['hub.mode']; const token = req.query['hub.verify_token']; const challenge = req.query['hub.challenge']; if (mode && token === VERIFY_TOKEN) { res.status(200).send(challenge); } else { res.sendStatus(403); } }); Step 7: Test Your Integration Start your server and test sending and receiving messages. node server.js Use Postman or a similar tool to send a POST request to http://localhost:3000/send-message with the following JSON body: { "phoneNumber": "whatsapp:+1234567890", "message": "Hello from Node.js!" } Conclusion Integrating the Meta Cloud WhatsApp API with Node.js allows you to leverage the power of WhatsApp for your applications. Following these steps, you can set up a basic integration to send and receive messages. Explore the API documentation further to unlock more features and capabilities for your applications. #NodeJS #WhatsAppAPI #MetaAPI #WebDevelopment #JavaScript #MessagingApp #CloudAPI #ExpressJS #FullStackDevelopment #APIntegration #Coding #SoftwareDevelopment #TechBlog https://developers.facebook.com/docs/whatsapp/cloud-api/
read on Medium
Jul 20, 2024
# contact.md

Let's Connect

Building something interesting? I'd love to hear about your next project.

built withNext.js · Tailwind · Vercel