Skip to main content

Command Palette

Search for a command to run...

http.HandlerFunc Behind The Scene

Published
3 min readView as Markdown
http.HandlerFunc Behind The Scene
I

A highly motivated and experienced full-stack developer with a proven track record of developing and deploying web applications. Skilled in a range of programming languages and frameworks, as well as database technologies. Comfortable working in a fast-paced environment and able to adapt to new technologies quickly. A team player who is also able to work independently when required.

Go প্রোগ্রামিং এর HTTP সার্ভার সিস্টেমে http.HandlerFunc একটি অসাধারণ টুল। আজ আমরা জানবো এটা পর্দার আড়ালে কীভাবে কাজ করে আর কেন এটা এত দরকারী।

এটা আসলে কী সমস্যা সমাধান করে?

Go তে যখন কোনো HTTP রিকোয়েস্ট হ্যান্ডেল করতে হয়, তখন আমাদেরকে http.Handler interface ইমপ্লিমেন্ট করতে হয়:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

কিন্তু প্রতিটা রাউটের জন্য আলাদা আলাদা struct বানিয়ে এই interface ইমপ্লিমেন্ট করা বেশ ঝামেলার ব্যাপার:

// HandlerFunc ছাড়া ট্র্যাডিশনাল পদ্ধতি
type ProductsHandler struct{}

func (h ProductsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // Handle products...
}

// এভাবে ব্যবহার করতে হয়
http.Handle("/products", &ProductsHandler{})

অনেকগুলো রাউট থাকলে এভাবে কোড লেখা বেশ কষ্টকর হয়ে যায়!

Type Conversion এর জাদু

Go standard library তে http.HandlerFunc এর আসল কোড এরকম:

// ধাপ ১: একটা function type ডিফাইন করা
type HandlerFunc func(ResponseWriter, *Request)

// ধাপ ২: এই function type কে Handler interface ইমপ্লিমেন্ট করানো
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)  // এই লাইনেই সব জাদু!
}

যখন আপনি লিখেন:

http.HandlerFunc(yourFunction)

আপনি কোনো function কল করছেন না! আপনি একটা type conversion করছেন যেটা আপনার সাধারণ function কে http.Handler interface ইমপ্লিমেন্ট করে এমন একটা type এ কনভার্ট করে।

পুরো প্রসেস স্টেপ বাই স্টেপ

আপনার middleware তে যখন HandlerFunc ব্যবহার করেন তখন ঠিক কী হয় দেখি:

func corsMiddleware(next http.Handler) http.Handler {
    handleCors := func(w http.ResponseWriter, r *http.Request) {
        // CORS headers সেট করা
        next.ServeHTTP(w, r)
    }

    return http.HandlerFunc(handleCors)  // ← এই পার্টটাই গুরুত্বপূর্ণ
}

পুরো সিকুয়েন্স এরকম:

  1. আপনি handleCors নামে একটা anonymous function ডিফাইন করেন যার signature func(w http.ResponseWriter, r *http.Request)

  2. আপনি এই function কে http.HandlerFunc type এ কনভার্ট করেন http.HandlerFunc(handleCors) দিয়ে

  3. এই type conversion অটোমেটিক্যালি আপনার function কে একটা ServeHTTP মেথড দিয়ে দেয়

  4. যখন একটা HTTP request আসে:

    • সার্ভার আপনার রিটার্ন করা handler এর ServeHTTP কল করে

    • HandlerFunc type এর জন্য, এর ServeHTTP ইমপ্লিমেন্টেশন শুধু function নিজেকেই কল করে

    • এটা আপনার handleCors function কে request এবং response দিয়ে এক্সিকিউট করে

মেমরি রেপ্রেজেন্টেশন

পর্দার আড়ালে, http.HandlerFunc(handleCors) এরকম function conversion একটা স্পেশাল function value তৈরি করে:

কনভার্শন আগে:
handleCors = 0xc0001a2000  // আপনার function এর মেমরি অ্যাড্রেস

কনভার্শন পরে:
HandlerFunc = 0xc0001a2000  // একই অ্যাড্রেস, কিন্তু interface table সহ

কনভার্শন আসলে নতুন function তৈরি করে না - এটা শুধু আগের function কে type information দিয়ে wrap করে যেটা বলে "এটা ServeHTTP ইমপ্লিমেন্ট করে"।

কেন এটা অসাধারণ একটা ডিজাইন

এই প্যাটার্ন Go এর ব্যবহারিক ডিজাইনের দারুণ উদাহরণ:

  1. কোনো boilerplate নেই: যেকোনো সঠিক signature ওয়ালা function কে HTTP handler এ পরিণত করা যায়

  2. Type safety: কম্পাইলার নিশ্চিত করে যে আপনার function এর signature ঠিক আছে

  3. Interface satisfaction: আপনার function এখন কোনো explicit ঘোষণা ছাড়াই একটা interface ইমপ্লিমেন্ট করে

  4. Composability: এটা middleware প্যাটার্ন গুলোকে সহজ ও সুন্দর করে তোলে

HandlerFunc এর কমন প্যাটার্ন

ডাইরেক্ট Handler তৈরি:

http.HandleFunc("/products", func(w http.ResponseWriter, r *http.Request) {
    // Handle products
})

(এটা আসলে http.Handle("/products", http.HandlerFunc(func(...))) এর শর্টহ্যান্ড)

Closure সহ Handler Function:

func productHandler(products []Product) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Closure থেকে products অ্যাক্সেস করা
        json.NewEncoder(w).Encode(products)
    }
}

// ব্যবহার:
http.Handle("/products", productHandler(productList))

আপনার Middleware প্যাটার্ন:

func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("Request: %s %s", r.Method, r.URL.Path)
        next.ServeHTTP(w, r)
    })
}

মূল পয়েন্ট

http.HandlerFunc আসলে একটা handler তৈরি করার function নয় - এটা একটা type conversion যা সাধারণ function কে এমন একটা type এ পরিণত করে যা http.Handler interface ইমপ্লিমেন্ট করে। এই ছোট্ট জিনিসটাই Go এর HTTP handling এবং middleware প্যাটার্ন কে এত সুন্দর করেছে।

যখন আপনি middleware থেকে http.HandlerFunc(handleCors) রিটার্ন করেন, আপনি আসলে বলছেন: "এই function কে নিয়ে এমন কিছুতে পরিণত করো যেটা http.Handler interface ইমপ্লিমেন্ট করে, যাতে এটা যেখানে handler দরকার সেখানেই ব্যবহার করা যায়।"

এই কারণেই Go এর HTTP সার্ভার ডিজাইন এত flexible এবং composable - এটা সাধারণ function কে খুব কম কোড দিয়ে শক্তিশালী interface ইমপ্লিমেন্টেশনে পরিণত করে।

More from this blog

Low Level Design: গভীর থেকে বোঝা এবং আয়ত্ত করা

ভূমিকা: কেন এই Article? তুমি হয়তো programming শিখেছ। Variable, loop, function, data structure - সব জানো। কিন্তু যখন একটা বড় system বানাতে বসো, তখন মনে হয় কোথা থেকে শুরু করব? কীভাবে organize করব? Code লিখতে লিখতে হারিয়ে যাও একটা maze-এ। এই feeling...

Oct 15, 202520 min read71
Low Level Design: গভীর থেকে বোঝা এবং আয়ত্ত করা

Go-তে Interface কীভাবে Code Decouple করে?

একটা HTTP Server দিয়ে পুরো ব্যাপারটা বুঝে নেওয়া যাক আমরা সবাই জানি Go একটা সিম্পল ল্যাঙ্গুয়েজ, কিন্তু interface নিয়ে অনেকেরই confusion থাকে। আজকে আমরা দেখব কীভাবে interface আসলে তোমার code-কে flexible এবং maintainable বানায়। একটা real-world HTT...

Oct 14, 202520 min read5
Go-তে Interface কীভাবে Code Decouple করে?

তোমার Project-এ Coupled Code কীভাবে খুঁজে বের করবে?

Coupled code খোঁজা মানে হচ্ছে তোমার codebase-এ এমন জায়গা খুঁজে বের করা যেখানে একটা অংশ আরেকটার উপর বেশি depend করছে। এটা একটা detective work — তুমি clue খুঁজবে, pattern দেখবে, এবং সমস্যা চিহ্নিত করবে। চলো step by step শিখি কীভাবে এটা করতে হয়। কেন ...

Oct 14, 202510 min read2

Go-তে Object (Struct Instance) তৈরির সম্পূর্ণ গাইড

Go programming শেখার সময় একটা জিনিস খুব তাড়াতাড়ি বুঝতে হয় - কীভাবে object তৈরি করতে হয়। অন্য language যেমন Java বা Python এ class আছে, কিন্তু Go-তে আছে struct। আর struct এর instance বানানোই হলো object তৈরি করা। আজকের এই blog এ আমরা দেখব Go-তে ob...

Oct 13, 202524 min read3
Go-তে Object (Struct Instance) তৈরির সম্পূর্ণ গাইড
I

Imran Hasan

61 posts

Full-stack developer with experience in developing and managing web applications. Skilled in React, Node.js, HTML, CSS, and JavaScript. Experience in managing website hosting and security.