
Viis aastat tagasi alustasin , see andis vÔimaluse Golangi Ôppimiseks. MÔistsin, et Go on vÔimas keel, mille vÔimalusi tÀiendavad mitmed teegid. Go on universaalne: selle abil on lihtne arendada serverirakendusi.
See artikkel on pĂŒhendatud Go-s serveri kirjutamisele. Alustame lihtsatest asjadest, nagu "Tere maailm!", ja lĂ”petame rakendusega, millel on jĂ€rgmised vĂ”imalused:
â Letâs Encrypti kasutamine HTTPS-i jaoks.
â Töö API marsruutijana.
â Töö middlewareâiga.
â Statiliste failide töötlemine.
â Korralik lĂ”petamine.
Skillbox soovitab: Praktiline kursus .
Tuletame meelde: kĂ”igile «Habra» lugejatele â 10 000 rubla soodustus, kui registreerite end Skillboxi mis tahes kursusele promokoodi «Habr» abil.
Tere, maailm!
Veebiserveri loomine Go-s on vÀga kiire. Siin on nÀide töötlejast, mis naaseb lubatud "Tere, maailm!".
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Tere maailm!")
})
http.ListenAndServe(":80", nil)
}PÀrast seda, kui rakendus kÀivitada ja lehte avada , nÀete kohe teksti "Tere, maailm!" (loomulikult, kui kÔik töötab Ôigesti).
Edasi kavatseme töötlejat mitu korda kasutada, kuid esmalt mĂ”istame, kuidas kĂ”ik on ĂŒles seatud.
net/http
NÀites kasutati paketti , mis on Go-s peamine vahend serverite ja HTTP-kliendi arendamiseks. Koodi parema mÔistmise nimel tutvume kolme olulise elemendi tÀhendusega: http.Handler, http.ServeMux ja http.Server.
HTTP töötlejad
Kui saame pĂ€ringu, analĂŒĂŒsib töötleja selle ja vormib vastuse. Go-s on töötlejad rakendatud jĂ€rgmiselt:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}Esimeses nĂ€ites kasutatakse abifunktsiooni http.HandleFunc. See ĂŒmbritseb teise funktsiooni, mis omakorda vĂ”tab vastu http.ResponseWriter ja http.Request funktsioonis ServeHTTP.
Teisiti öeldes, on töötlejad Golangis esitatud ĂŒhtse liidesena, mis annab programmeerijale palju vĂ”imalusi. NĂ€iteks rakendatakse middleware töötleja kaudu, kus ServeHTTP teeb kĂ”igepealt midagi ja seejĂ€rel kutsub teise töötleja ServeHTTP meetodi.
Nagu juba mainitud, kujundavad töötlejad lihtsalt vastuseid pÀringutele. Kuid millist töötlejat on konkreetsel hetkel vaja kasutada?
PĂ€ringute marsruutimine
Ăige valiku tegemiseks kasutage HTTP-multiplexerit. Mitmes raamatukogus nimetatakse seda muxeriks vĂ”i ruuteriks, kuid tĂ”epoolest on need kĂ”ik ĂŒhesugused. Multiplexer'i funktsioon on analĂŒĂŒsida pĂ€ringu teed ja valida vastav töötleja.
Kui on vajalik keeruka marsruutimise tugi, siis on parem kasutada kolmandate osapoolte raamatukogusid. Ăks kĂ”ige arenenumatest on ja , need raamatukogud vĂ”imaldavad hĂ”lpsasti rakendada vahepealse töötlemise lahendusi. Nende abil saate seadistada wildcard-marsruutimise ja teisi ĂŒlesandeid. Nende eeliseks on ĂŒhilduvus standardsete HTTP-töötlejatega. Tulemusena saate kirjutada lihtsa koodi, millel on vĂ”imalus seda tulevikus kohandada.
Töötamine keerukate raamistikudega tavapÀrases olukorras nÔuab mitte vÀga standardseid lahendusi, mis oluliselt raskendab vaikimisi töötlejate kasutamist. Enamik rakendusi saavad hakkama vaikimisi raamatukogu ja lihtsa ruuteriga.
PÀringute töötlemine
Lisaks vajame komponenti, mis "kuulab" sisse tulevaid ĂŒhendusi ja suunab kĂ”ik pĂ€ringud Ă”ige töötleja juurde. Selle ĂŒlesande tĂ€idab probleemideta http.Server.
Allpool on nĂ€idatud, et server vastutab kĂ”igi ĂŒlesannete eest, mis on seotud ĂŒhenduste töötlemisega. NĂ€iteks toimub siin TLS-protokolli töötlemine. http.ListenAndServeri rakendamiseks kasutatakse standardset HTTP-serverit.
NĂŒĂŒd vaatame keerulisemaid nĂ€iteid.
Lisamine Letâs Encrypt
Vaikimisi töötab meie rakendus HTTP-protokolli kaudu, kuid on soovitatav kasutada HTTPS-protokolli. Go-s on see lihtne. Kui olete saanud sertifikaadi ja privaatvÔtme, piisab, kui kutsuda esile ListenAndServeTLS, osutades Ôigele sertifikaadi ja vÔtme failile.
http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil)Alati on vÔimalik paremini teha.
pakub tasuta sertifikaate automaatse uuendamise vÔimalusega. Teenuse kasutamiseks on vajalik pakett autocert.
Lihtsaim viis selle seadistamiseks on kasutada autocert.NewListener meetodit koos http.Serve'iga. See meetod vÔimaldab hankida ja uuendada TLS-sertifikaate, samal ajal kui HTTP-server kÀsitleb pÀringuid:
http.Serve(autocert.NewListener("example.com"), nil)Kui avame brauseris , saame HTTPS-vastuse âHello, world!â.
Kui vajame tÀiendavat seadistamist, on soovitatav kasutada autocert.Manager haldurit. SeejÀrel loome oma http.Server eksemplari (kuni siiamaani kasutasime vaikeversiooni) ja lisame halduri serveri TLSConfig'i:
m := &autocert.Manager{
Cache: autocert.DirCache("golang-autocert"),
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example.org", "www.example.org"),
}
server := &http.Server{
Addr: ":443",
TLSConfig: m.TLSConfig(),
}
server.ListenAndServeTLS("", "")See on lihtne viis tÀieliku HTTPS toe rakendamiseks koos automaatse sertifikaadi uuendamisega.
Kohandatud marsruutide lisamine
Standardteekide vaikemarsruuter, mis on kaasatud standardbiblioteeki, on hea, kuid vÀga lihtne. Enamikus rakendustes on vaja keerukamat marsruutimist, sealhulgas pesamarsruute ja wildcard-marsruute vÔi samuti mallide ja marsruutide parameetrite mÀÀramist.
Selles olukorras on soovitatav kasutada pakette ja Meie viimane teema on see, kuidas töötada . Allpool on nÀide.
Antud on fail api/v1/api.go, mis sisaldab marsruute meie API-le:
/ 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
}Seadistame marsruutide eelprefiksiks api/vq peafailis.
Saame selle mountida meie peamise marsruudile api/v1/ prefiksi alla tagasi meie pÔhiÀpis:
// 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())Go-s keeruliste marsruutidega töötamise lihtsus vÔimaldab lihtsustada suuremate keeruliste rakenduste haldamist.
Töötamine vahekihiga
Vahekihtide töötamisel ĂŒmbritsetakse ĂŒhte HTTP-kĂ€sitlejat teisega, mis vĂ”imaldab kiiresti teostada autentimist, tihendamist, logimist ja mĂ”ningaid muid funktsioone.
NÀiteks vaatame http.Handler liidest, millega kirjutame HTTP-kÀsitleja, mis teostab teenuse kasutajate autentimist.
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
}
// Eeldades, et autentimine on lÀbitud, kÀivita algne kÀsitleja
next.ServeHTTP(w, r)
})
}On ka kolmandate osapoolte marsruuterid, nagu chi, mis vÔimaldavad laiendada vahekihitöötluse funktsionaalsust.
Töötamine staatiliste failidega
Go standardraamatukogus on olemas vÔimalused staatilise sisu töötlemiseks, sealhulgas piltide ning JavaScripti ja CSS-failide jaoks. Neile pÀÀseb juurde funktsiooni http.FileServer kaudu, mis tagastab töötleja, mis jagab faile mÀÀratud kataloogist.
func NewRouter() http.Handler {
router := chi.NewRouter()
r.Get("/{name}", HelloName)
// Staatiliste failide jagamise seadistus
staticPath, _ := filepath.Abs("../../../static/")
fs := http.FileServer(http.Dir(staticPath))
router.Handle("/*", fs)
return rOluline on meeles pidada, et http.Dir kuvab katalooge ainult siis, kui seal ei ole pÔhifaili index.html. Sellisel juhul, et vÀltida katalooge riskimist, tuleks kasutada paketti .
Korrektselt töö lÔpetamine
Go-s on olemas ka selline funktsioon nagu HTTP-serveri korrektselt töö lĂ”petamine. Seda saab teha meetodi Shutdown() abil. Server kĂ€ivitatakse goroutine'is ning seejĂ€rel kuulatakse signaali katkestamise vastuvĂ”tmiseks. Nii varsti kui signaal on saadud, lĂŒlitatakse server vĂ€lja, kuid mitte kohe, vaid mĂ”ne sekundi pĂ€rast.
handler := server.NewRouter()
srv := &http.Server{
Handler: handler,
}
go func() {
srv.Serve(autocert.NewListener(domains...))
}()
// Oota katkestust
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
// Proovi korralikku sulgemist
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)KokkuvÔtteks
Go â vĂ”imas keel, millel on praktiliselt universaalne standardraamatukogu. Selle vaikimisi vĂ”imalused on ĂŒsna laiad, ja neid saab tugevdada liideste abil â see vĂ”imaldab arendada tĂ”eliselt usaldusvÀÀrseid HTTP-servereid.
Skillbox soovitab:
- Kaheaastane praktiline kursus .
- Hariduslik veebikursus .
- Praktiline aastakursus .
Allikas: habr.com
