برنامه نویسی

بازگرداندن چارچوب وب جین از ابتدا در GO

شرح تصویر

Leapcell: بهترین میزبانی وب بدون سرور

اجرای یک روتر HTTP شبیه به جین با استفاده از net بسته بندی در GO

1. مقدمه

در توسعه وب مدرن ، یک سیستم مسیریابی کارآمد و انعطاف پذیر یکی از مؤلفه های اصلی ساخت برنامه های وب است. زبان برنامه نویسی GO به دلیل عملکرد بالا ، سادگی و کتابخانه استاندارد قدرتمند ، در زمینه توسعه وب بسیار مورد علاقه است. در net/http بسته بندی در GO اجرای یک سرور HTTP در کتابخانه استاندارد است. اگرچه قدرتمند است ، اما نسبتاً پایین است. اگر می خواهید مسیریابی مانند چارچوب های وب سبک مانند جین را انجام دهید ، می توانیم خودمان یک روتر ساده را پیاده سازی کنیم. در این مقاله مقدمه مفصلی در مورد نحوه استفاده از net بسته بندی شده برای پیاده سازی یک سرور HTTP مشابه GIN. در عین حال ، آن را به دانش مربوط به HTTP ، روش های اجرای مسیریابی مشترک و نحوه اجرای میان افزار بر اساس این موضوع تبدیل می شود.

2. بررسی اصول HTTP

2.1 درخواست و پاسخ HTTP

HTTP (پروتکل انتقال HyperText) پروتکل است که برای انتقال فشار خون بالا استفاده می شود و پایه و اساس برنامه های وب است. یک درخواست HTTP معمولاً از قسمت های زیر تشکیل شده است:

  • خط درخواست: این شامل روش درخواست است (مانند GETبا POSTبا PUTبا DELETE، و غیره) ، URI درخواست شده (شناسه منابع یکنواخت) و نسخه HTTP.
  • هدر را درخواست کنید: آنها حاوی اطلاعات اضافی در مورد درخواست هستند ، مانند User-Agentبا Content-Type، و غیره
  • بدنه درخواست کردن: حاوی داده های درخواست است که معمولاً در آن استفاده می شود POST یا PUT درخواست ها

پاسخ HTTP همچنین از چندین بخش تشکیل شده است:

  • خط وضعیت: این شامل نسخه HTTP ، کد وضعیت است (به عنوان مثال ، 200 نشان دهنده موفقیت است ، 404 نشان داده نشده است ، 500 خطای سرور داخلی و غیره را نشان می دهد) و پیام وضعیت.
  • سرور پاسخ: آنها حاوی اطلاعات اضافی در مورد پاسخ هستند ، مانند Content-Typeبا Content-Length، و غیره
  • بدن پاسخ: این شامل داده های پاسخ ، مانند صفحه HTML ، داده های JSON و غیره است.

2.2 روش HTTP

روشهای متداول HTTP عبارتند از:

  • بدست آوردن: از آن برای بازیابی منابع استفاده می شود.
  • پست: از آن برای ارسال داده ها به سرور ، معمولاً برای ایجاد منابع جدید استفاده می شود.
  • قرار دادن: از آن برای به روزرسانی منابع استفاده می شود.
  • حذف کردن: از آن برای حذف منابع استفاده می شود.

روشهای مختلف HTTP دارای معناشناسی متفاوتی هستند و هنگام طراحی یک سیستم مسیریابی باید درخواست ها با توجه به روش های مختلف انجام شود.

3. روشهای اجرای مسیریابی مشترک

3.1 مسیریابی استاتیک

مسیریابی استاتیک ساده ترین روش مسیریابی است ، که یک مسیر URL ثابت را به یک عملکرد خاص کنترل کننده ترسیم می کند. به عنوان مثال ، نقشه برداری /about مسیر به عملکرد کنترل کننده که صفحه درباره آن را نشان می دهد.

3.2 مسیریابی پویا

مسیریابی پویا اجازه می دهد تا پارامترها در مسیر URL گنجانده شوند و این پارامترها را می توان در عملکرد کنترل کننده بازیابی کرد. به عنوان مثال ، :id در /users/:id پارامتری است که می تواند برای بازیابی اطلاعات در مورد یک کاربر خاص استفاده شود.

3.3 مسیریابی منظم بیان

مسیریابی بیان منظم امکان استفاده از عبارات منظم را برای مطابقت با مسیرهای URL فراهم می کند. این روش انعطاف پذیرتر است و می تواند قوانین پیچیده مسیریابی را اداره کند. به عنوان مثال ، استفاده از عبارات منظم برای مطابقت با تمام مسیرهای URL که به پایان می رسد .htmlبشر

4. ایده های طراحی

برای اجرای عملکرد مسیریابی ، ما باید:

  • مسیر و روش درخواست HTTP را تجزیه کنید.
  • توابع کنترل کننده را برای مسیرها و روشهای مختلف ذخیره کنید.
  • پارامترهای مسیریابی پویا را تجزیه کنید.
  • 404 خطا را انجام دهید.

ما از map ساختار برای ذخیره قوانین مسیریابی. هر مسیر با روشهای مختلف HTTP مطابقت دارد ، که می تواند به طور مؤثر با درخواست ها مطابقت داشته باشد. به طور خاص ، ما از تو در تو استفاده خواهیم کرد mapبشر کلید بیرونی map روش HTTP ، کلید داخلی است map مسیر URL است و مقدار عملکرد کنترل کننده مربوطه است.

5. اجرای کد

package main

import (
    "fmt"
    "net/http"
    "strings"
)

// Router struct is used to store routing rules
type Router struct {
    routes map[string]map[string]http.HandlerFunc
}

// NewRouter creates a new router instance
func NewRouter() *Router {
    return &Router{
        routes: make(map[string]map[string]http.HandlerFunc),
    }
}

// Handle method is used to register routes
func (r *Router) Handle(method, path string, handler http.HandlerFunc) {
    if _, ok := r.routes[method];!ok {
        r.routes[method] = make(map[string]http.HandlerFunc)
    }
    r.routes[method][path] = handler
}

// ServeHTTP method is used to parse HTTP requests and call the corresponding handler functions
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    methodRoutes, ok := r.routes[req.Method]
    if!ok {
        http.NotFound(w, req)
        return
    }

    handler, ok := methodRoutes[req.URL.Path]
    if!ok {
        // Handle dynamic routing
        for route, h := range methodRoutes {
            if params := matchDynamicRoute(route, req.URL.Path); params != nil {
                req.URL.Query().Set("params", strings.Join(params, ","))
                h(w, req)
                return
            }
        }
        http.NotFound(w, req)
        return
    }

    handler(w, req)
}

// matchDynamicRoute function is used to match dynamic routes
func matchDynamicRoute(route, path string) []string {
    routeParts := strings.Split(route, "/")
    pathParts := strings.Split(path, "/")

    if len(routeParts) != len(pathParts) {
        return nil
    }

    var params []string
    for i, part := range routeParts {
        if strings.HasPrefix(part, ":") {
            params = append(params, pathParts[i])
        } else if part != pathParts[i] {
            return nil
        }
    }

    return params
}

func main() {
    router := NewRouter()

    // Register static route
    router.Handle("GET", "/", func(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintf(w, "Hello, world!")
    })

    // Register dynamic route
    router.Handle("GET", "/hello/:name", func(w http.ResponseWriter, req *http.Request) {
        params := req.URL.Query().Get("params")
        name := strings.Split(params, ",")[0]
        fmt.Fprintf(w, "Hello, %s!", name)
    })

    http.ListenAndServe(":8080", router)
}

توضیح کد

  • Router ساختار: از آن برای ذخیره قوانین مسیریابی استفاده می شود و از تو در تو استفاده می کند map برای ذخیره توابع کنترل کننده مربوط به روشهای مختلف HTTP و مسیرهای URL.
  • NewRouter عملکرد: از آن برای ایجاد یک نمونه روتر جدید استفاده می شود.
  • Handle روش: از آن برای ثبت مسیرها ، ذخیره روش HTTP ، مسیر URL و عملکرد کنترل کننده در Router ساختار.
  • ServeHTTP روش: از آن برای تجزیه درخواست های HTTP استفاده می شود. ابتدا بررسی می کند که آیا روش HTTP درخواست شده وجود دارد ، و سپس بررسی می کند که آیا مسیر URL مطابقت دارد یا خیر. اگر مسیر استاتیک تطبیق وجود نداشته باشد ، سعی خواهد کرد با مسیر پویا مطابقت داشته باشد.
  • matchDynamicRoute عملکرد: از آن برای مطابقت با مسیرهای پویا استفاده می شود و بررسی می کند که آیا پارامترهای موجود در مسیر URL مطابقت دارد یا خیر.

6. در حال اجرا و آزمایش

کد را به عنوان ذخیره کنید main.go و آن را اجرا کنید:

go run main.go

سپس بازدید کنید:

  • http://localhost:8080/ بازگرداندن "Hello, world!"
  • http://localhost:8080/hello/Go بازگرداندن "Hello, Go!"
  • بازدید از مسیرهای دیگر باز خواهد گشت 404 Not Found

7. اجرای میان افزار

Middleware تابعی است که قبل یا بعد از رسیدگی به درخواست اجرا می شود. این می تواند برای ورود به سیستم ، تأیید اعتبار ، رسیدگی به خطا و غیره استفاده شود. اجرای میان افزار در روتر ما بسیار ساده است. ما فقط باید یک نوع عملکردی را که دریافت می کند تعریف کنیم http.HandlerFunc و جدید را برمی گرداند http.HandlerFuncبشر

// Middleware is a middleware function type
type Middleware func(http.HandlerFunc) http.HandlerFunc

// Logger is a simple logging middleware
func Logger(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, req *http.Request) {
        fmt.Printf("Received %s request for %s\n", req.Method, req.URL.Path)
        next(w, req)
    }
}

func main() {
    router := NewRouter()

    // Register static route and apply middleware
    router.Handle("GET", "/", Logger(func(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintf(w, "Hello, world!")
    }))

    // Register dynamic route and apply middleware
    router.Handle("GET", "/hello/:name", Logger(func(w http.ResponseWriter, req *http.Request) {
        params := req.URL.Query().Get("params")
        name := strings.Split(params, ",")[0]
        fmt.Fprintf(w, "Hello, %s!", name)
    }))

    http.ListenAndServe(":8080", router)
}

توضیح کد

  • Middleware نوع: این یک نوع عملکرد میانی را تعریف می کند که دریافت می کند http.HandlerFunc و جدید را برمی گرداند http.HandlerFuncبشر
  • Logger عملکرد: این یک میانی نرم افزار ورود به سیستم ساده است که قبل از رسیدگی به درخواست ، روش درخواست و مسیر URL را چاپ می کند.
  • در main عملکرد ، ما اعمال می کنیم Logger واسطه به عملکرد کنترل کننده هر مسیر.

8. خلاصه

این آموزش نحوه استفاده از net/http بسته بندی به زبان Go برای اجرای یک روتر وب ساده. در عین حال ، دانش مربوط به HTTP ، روشهای اجرای مسیریابی مشترک و نحوه اجرای میان افزار را بر اساس این موضوع معرفی می کند. شما می توانید عملکرد را بر این اساس گسترش دهید ، مانند:

  • پشتیبانی از روشهای HTTP بیشتر ، مانند PUTبا DELETE، و غیره
  • اضافه کردن توابع میان افزار پیچیده تر ، مانند احراز هویت ، محدود کردن نرخ و غیره
  • اجرای تجزیه پارامتر پیشرفته تر ، مانند مسیریابی منظم بیان.

به این ترتیب ، ما نه تنها می توانیم به اصول کار اساسی سرورهای HTTP تسلط داشته باشیم بلکه چارچوب های وب خود را نیز سفارشی کنیم و از عملکرد و انعطاف پذیری بالا زبان GO لذت ببریم.

Leapcell: بهترین میزبانی وب بدون سرور

سرانجام ، من می خواهم بهترین سیستم عامل را برای استقرار خدمات GO توصیه کنم: جهش

شرح تصویر

🚀 با زبان مورد علاقه خود بسازید

با زحمت در JavaScript ، Python ، Go یا Rust.

🌍 پروژه های نامحدود را به صورت رایگان مستقر کنید

فقط آنچه را که استفاده می کنید بپردازید – بدون درخواست ، بدون هزینه.

⚡ پرداخت به عنوان شما ، بدون هزینه های پنهان

بدون هزینه بیکار ، فقط مقیاس پذیری بدون درز.

شرح تصویر

📖 اسناد ما را کاوش کنید

🔹 ما را در توییتر دنبال کنید: leapcellhq

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا