بازگرداندن چارچوب وب جین از ابتدا در 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