Pangembangan server web ing Golang - saka prasaja nganti kompleks
Limang taun kepungkur aku miwiti ngembangake Gophish, iki menehi kesempatan kanggo sinau Golang. Aku nyadari yen Go minangka basa sing kuat, dilengkapi karo akeh perpustakaan. Go iku serbaguna: utamane, bisa digunakake kanggo ngembangake aplikasi sisih server tanpa masalah.
Artikel iki babagan nulis server ing Go. Ayo diwiwiti kanthi prasaja kaya "Hello world!" lan mungkasi aplikasi kanthi kapabilitas ing ngisor iki:
- Nggunakake Ayo Encrypt kanggo HTTPS.
- Makarya minangka router API.
- Nggarap middleware.
- Pangolahan file statis.
- Mati sing bener.
Kita ngelingake:kanggo kabeh sing maca "Habr" - diskon 10 rubel nalika ndhaptar kursus Skillbox nggunakake kode promosi "Habr".
Halo, jagad!
Sampeyan bisa nggawe server web ing Go kanthi cepet banget. Iki minangka conto nggunakake pawang sing ngasilake "Halo, jagad!" sing dijanjekake ing ndhuwur.
Sawise iki, yen sampeyan mbukak aplikasi lan mbukak kaca localhost, banjur sampeyan bakal langsung ndeleng teks "Halo, jagad!" (yen kabeh bisa digunakake kanthi bener, mesthi).
Kita bakal nggunakake handler kaping pirang-pirang mengko, nanging pisanan ayo kang ngerti carane kabeh bisa.
net / http
Conto digunakake paket net/http, iku alat utama ing Go kanggo ngembangake server lan klien HTTP. Kanggo ngerti kode, ayo kang ngerti makna saka telung unsur penting: http.Handler, http.ServeMux lan http.Server.
panangan HTTP
Nalika kita nampa panjalukan, pawang nganalisa lan ngasilake respon. Handler ing Go ditindakake kaya ing ngisor iki:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
Conto pisanan nggunakake fungsi helper http.HandleFunc. Iku mbungkus fungsi liyane, kang siji njupuk http.ResponseWriter lan http.Request menyang ServeHTTP.
Ing tembung liyane, pawang ing Golang presented ing antarmuka siji, kang menehi akeh pilihan kanggo programmer. Dadi, contone, middleware dileksanakake nggunakake handler, ngendi ServeHTTP pisanan nindakake soko lan banjur nelpon cara ServeHTTP handler liyane.
Kaya sing kasebut ing ndhuwur, pawang mung ngasilake respon kanggo panjaluk. Nanging pawang tartamtu sing kudu digunakake ing wektu tartamtu?
Njaluk Routing
Kanggo nggawe pilihan sing tepat, gunakake multiplexer HTTP. Ing sawetara perpustakaan diarani muxer utawa router, nanging kabeh padha. Fungsi multiplexer punika njelasno path request lan pilih handler cocok.
Nggarap kerangka kompleks ing kahanan normal mbutuhake solusi non-standar, lan iki nggawe rumit panggunaan panangan standar. Kanggo nggawe mayoritas aplikasi, kombinasi perpustakaan standar lan router sing prasaja bakal cukup.
Pangolahan pitakon
Kajaba iku, kita butuh komponen sing bakal "ngrungokake" kanggo sambungan sing mlebu lan ngarahake kabeh panjaluk menyang pawang sing bener. http.Server bisa gampang nangani tugas iki.
Ing ngisor iki nuduhake yen server tanggung jawab kanggo kabeh tugas sing ana hubungane karo pangolahan sambungan. Iki, contone, dianggo nggunakake protokol TLS. Kanggo ngleksanakake panggilan http.ListenAndServer, server HTTP standar digunakake.
Saiki ayo ndelok conto sing luwih rumit.
Nambahake Ayo Encrypt
Kanthi gawan, aplikasi kita nganggo protokol HTTP, nanging disaranake nggunakake protokol HTTPS. Iki bisa rampung tanpa masalah ing Go. Yen sampeyan wis nampa sertifikat lan kunci pribadi, mula cukup kanggo ndhaptar ListenAndServeTLS kanthi sertifikat lan file kunci sing bener.
Ayo Encrypt menehi sertifikat free karo nganyari maneh otomatis. Kanggo nggunakake layanan kasebut, sampeyan butuh paket autocert.
Cara paling gampang kanggo ngatur iku nggunakake autocert.NewListener cara ing kombinasi karo http.Serve. Cara kasebut ngidini sampeyan entuk lan nganyari sertifikat TLS nalika server HTTP ngolah panjaluk:
Yen kita mbukak ing browser example.com, kita bakal nampa respon HTTPS "Halo, donya!"
Yen sampeyan mbutuhake konfigurasi sing luwih rinci, sampeyan kudu nggunakake manajer autocert.Manager. Banjur kita nggawe conto http.Server kita dhewe (nganti saiki digunakake minangka standar) lan nambah manajer menyang server TLSConfig:
Iki minangka cara sing gampang kanggo ngetrapake dhukungan HTTPS lengkap kanthi nganyari sertifikat otomatis.
Nambahake rute khusus
Router standar sing kalebu ing perpustakaan standar apik, nanging dhasar banget. Umume aplikasi mbutuhake rute sing luwih rumit, kalebu rute nested lan wildcard, utawa prosedur kanggo nyetel pola lan paramèter path.
Ing kasus iki, iku worth nggunakake paket gorila / mux ΠΈ go-chi/chi. Kita bakal sinau cara nggarap sing terakhir - conto ditampilake ing ngisor iki.
Diwenehake yaiku file api/v1/api.go sing ngemot rute kanggo API kita:
/ HelloResponse is the JSON representation for a customized message
type HelloResponse struct {
Message string `json:"message"`
}
// HelloName returns a personalized JSON message
func HelloName(w http.ResponseWriter, r *http.Request) {
name := chi.URLParam(r, "name")
response := HelloResponse{
Message: fmt.Sprintf("Hello %s!", name),
}
jsonResponse(w, response, http.StatusOK)
}
// NewRouter returns an HTTP handler that implements the routes for the API
func NewRouter() http.Handler {
r := chi.NewRouter()
r.Get("/{name}", HelloName)
return r
}
Kita nyetel awalan api/vq kanggo rute ing file utama.
Kita banjur bisa masang iki menyang router utama ing ngisor api / v1 / awalan bali ing aplikasi utama kita:
// NewRouter returns a new HTTP handler that implements the main server routes
func NewRouter() http.Handler {
router := chi.NewRouter()
router.Mount("/api/v1/", v1.NewRouter())
return router
}
http.Serve(autocert.NewListener("example.com"), NewRouter())
Gampang nggarap rute rumit Go bisa nggawe gampang struktur lan pangopènan aplikasi sing kompleks.
Nggarap middleware
Pementasan kalebu mbungkus siji panangan HTTP karo liyane, supaya bisa cepet nindakake otentikasi, kompresi, logging, lan sawetara fungsi liyane.
Minangka conto, ayo goleki antarmuka http.Handler; kita bakal nggunakake aplikasi kasebut kanggo nulis pawang sing ngotentikasi pangguna layanan.
func RequireAuthentication(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !isAuthenticated(r) {
http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
return
}
// Assuming authentication passed, run the original handler
next.ServeHTTP(w, r)
})
}
Ana router pihak katelu, kayata chi, sing ngidini sampeyan ngluwihi fungsi middleware.
Nggarap file statis
Pustaka standar Go kalebu kemampuan kanggo nggarap konten statis, kalebu gambar, file JavaScript lan CSS. Padha bisa diakses liwat fungsi http.FileServer. Iki ngasilake handler sing nglayani file saka direktori tartamtu.
Perlu dieling-eling yen http.Dir nampilake isi direktori yen ora ngemot file index.html utama. Ing kasus iki, kanggo nyegah direktori dikompromi, sampeyan kudu nggunakake paket kasebut unindexed.
Mati sing bener
Go uga duwe fitur sing diarani mateni server HTTP. Iki bisa ditindakake kanthi nggunakake metode Shutdown (). Server diwiwiti ing goroutine, banjur saluran dirungokake kanggo nampa sinyal interrupt. Sanalika sinyal ditampa, server dipateni, nanging ora langsung, nanging sawise sawetara detik.
handler := server.NewRouter()
srv := &http.Server{
Handler: handler,
}
go func() {
srv.Serve(autocert.NewListener(domains...))
}()
// Wait for an interrupt
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
// Attempt a graceful shutdown
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)
Minangka kesimpulan
Go minangka basa sing kuat kanthi perpustakaan standar sing meh universal. Kapabilitas standar kasebut amba banget, lan bisa ditambah kanthi nggunakake antarmuka - iki ngidini sampeyan ngembangake server HTTP sing bisa dipercaya.