
Viis aastat tagasi alustasin ma , see andis vÔimaluse Ôppida Golangi. Ma mÔistsin, et Go on vÔimas keel, mille vÔimalusi tÀiendab arvukalt teeke. Go on universaalne: nÀiteks saab seda kasutada serverirakenduste arendamiseks probleemideta.
See artikkel on pĂŒhendatud serveri kirjutamisele Go-s. Alustame lihtsatest asjadest, nagu âTere maailm!â, ja lĂ”petame rakendusega, millel on jĂ€rgmised vĂ”imalused:
â Letâs Encrypti kasutamine HTTPS-iks.
â Töötamine API marsruutijana.
â Töötamine middleware'iga.
â Staatiliste failide töötlemine.
â Korralik vĂ€ljalĂŒlitamine.
Skillbox soovitab: Praktiline kursus .
Tuletame meelde: kĂ”igile «Habr» lugejatele â 10 000 rubla allahindlus igale Skillboxi kursusele, kasutades sooduskoodi «Habr».
Tere, maailm!
Veebiserveri loomine Go-s on vĂ€ga kiire. Siin on nĂ€ide toimimisest töötlusest, mis tagastab eelnevalt mainitud â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 leht avada , nĂ€ete kohe teksti âTere, maailm!â (muidugi, kui kĂ”ik töötab Ă”igesti).
Edasi kasutame töötlust korduvalt, kuid kÔigepealt vÔtame aega mÔistmiseks, kuidas kÔik toimib.
net/http
NÀites kasutati paketti , see on Go pÔhivahend serverite ja HTTP-kliendi arendamiseks. Koodi mÔistmiseks vaatame kolme olulise elemendi tÀhendust: http.Handler, http.ServeMux ja http.Server.
HTTP-töötlustooted
Kui me saame pĂ€ringu, analĂŒĂŒsib töötlus selle ja koostab vastuse. Go-s on töötlejad rakendatud jĂ€rgmiselt:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}Esimeses nĂ€ites kasutatakse abifunktsiooni http.HandleFunc. See ĂŒmbritseb teist funktsiooni, mis omakorda vĂ”tab http.ResponseWriter ja http.Request'i ServeHTTP-s.
TeisisĂ”nu, töötlejad Golangis esindavad ĂŒhtset liidest, mis pakub programmeerijale palju vĂ”imalusi. NĂ€iteks on middleware rakendatud lĂ€bi töötleja, kus ServeHTTP teeb esmalt midagi ja seejĂ€rel kutsub teise töötleja ServeHTTP meetodi.
Nagu eelpool öeldud, töötlejad koostavad lihtsalt vastuseid pÀringutele. Kuid millist töötlejat tuleks kasutada konkreetsel hetkel?
PĂ€ringute marsruutimine
Ăige valiku tegemiseks kasutage HTTP-multiplexerit. MĂ”nedes raamatukogudes nimetatakse seda muxeriks vĂ”i ruuteriks, kuid kĂ”ik need on sama asi. Multiplexer'i funktsioon on analĂŒĂŒsida pĂ€ringu teed ja valida vastav töötleja.
Kui on vajalik keerulise marsruutimise tugi, on parem kasutada kolmandate osapoolte raamatukogusid. MĂ”ned kĂ”ige arenenumad on: ja , need raamatukogud vĂ”imaldavad rakendada vahepealseid töötlemisi ilma eriliste probleemideta. Nende abil on vĂ”imalik seadistada wildcards-marsruutimist ja lahendada mitmeid muid ĂŒlesandeid. Nende eeliseks on ĂŒhilduvus standardsete HTTP-töötlejatega. Tulemuseks on, et saate kirjutada lihtsa koodi, millel on tulevikus muudetava koodi vĂ”imalus.
Töökeeruliste raamistikudega tavaliselt nÔuab ebatavalisi lahendusi, mis oluliselt keerukamaks muudab standardsete töötlejate kasutamise. Enamikule rakendustele piisab vaikimisi raamatukogu ja lihtsa ruuteri kombinatsioonist.
PÀringute töötlemine
Lisaks on meil vajalik komponent, mis âkuulabâ sissetulevaid ĂŒhendusi ja suunab kĂ”ik pĂ€ringud Ă”igele töötlejale. Selle ĂŒlesandega saab hĂ”lpsasti hakkama http.Server.
Allpool on nĂ€idatud, et server vastutab kĂ”igi ĂŒlesannete eest, mis on seotud ĂŒhenduste töötlemisega. See hĂ”lmab nĂ€iteks TLS-protokolli tööd. http.ListenAndServe'i kutsumise rakendamiseks kasutatakse standardset HTTP-serverit.
NĂŒĂŒd vaatame keerulisemaid nĂ€iteid.
Letâs Encrypti lisamine
Vaikimisi töötab meie rakendus HTTP-protokolli abil, kuid soovitatakse kasutada HTTPS-protokolli. Go-s saab seda teha probleemideta. Kui olete saanud sertifikaadi ja privaatvÔtme, piisab, kui mÀÀrata ListenAndServeTLS koos Ôige sertifikaadi ja vÔtmefailiga.
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 meetodit autocert.NewListener koos http.Serve'iga. Meetod vÔimaldab saada ja uuendada TLS-sertifikaate, samal ajal kui HTTP-server töötleb pÀringuid:
http.Serve(autocert.NewListener("example.com"), nil)Kui avame brauseris , siis saame HTTPS-reaktsiooni «Tere, maailm!».
Kui vajate pÔhjalikumat seadistamist, siis tasub kasutada autocert.Manager'i. SeejÀrel loome oma http.Server'i instantsi (kuni praeguseni oleme kasutanud vaikeseadet) ja lisame halduri TLSConfig'i serverisse:
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 kogu HTTPS-toe rakendamiseks automaatse sertifikaadi uuendamisega.
Mitte-standardsete marsruutide lisamine
Vaikimisi marsruuter, mis on kaasatud standardteekidesse, on hea, kuid vÀga lihtne. Enamikes rakendustes on vajalik keerulisem marsruutimine, sealhulgas pesakonnad ja wildcard-marsruudid vÔi ƥabloonide ja teeparameetrite seadistamise protseduur.
Selles olukorras tasub kasutada pakette ja . Viimasega Ă”pime me töötama â allpool on nĂ€ide.
Antud on fail api/v1/api.go, mis sisaldab meie API marsruute:
/ 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
}Seame marsruutidele api/vq prefiksi peafailis.
Saame seejÀrel selle meie peamisse marsruuterisse lisada api/v1/ prefiksi all tagasi meie pÔhitarvutis:
// 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())Töötamine keeruliste marsruutidega Go-s vÔimaldab lihtsustada suure keeruliste rakenduste haldust.
Töötamine middleware'iga
Vahepealse töötlemise korral kasutatakse ĂŒhe HTTP-kĂ€itja mĂ€hkimist teise, mis vĂ”imaldab kiiresti teha autentimist, tihendamist, logimist ja mĂ”ned muud funktsioonid.
NÀiteks vaatame http.Handler'i liidest, mille abil kirjutame kasutajate autentimisega kÀitja.
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Àitame originaalkÀitjat
next.ServeHTTP(w, r)
})
}On olemas kolmanda osapoole marsruutijad, nagu chi, mis vÔimaldavad vahepealse töötlemise funktsionaalsust laiendada.
Töötamine staatiliste failidega
Go standardteek sisaldab vÔimalusi staatilise sisu kÀsitlemiseks, sealhulgas pilte ja JavaScripti ja CSS-faile. Neile pÀÀseb juurde http.FileServer'i funktsiooni kaudu. See tagastab kÀitja, mis edastab faile kindlast kataloogist.
func NewRouter() http.Handler {
router := chi.NewRouter()
r.Get("/{name}", HelloName)
// Kuidas seadistada staatiliste failide jagamist
staticPath, _ := filepath.Abs("../../static/")
fs := http.FileServer(http.Dir(staticPath))
router.Handle("/*", fs)
return rOluline on meeles pidada, et http.Dir kuvab kausta sisu vaid juhul, kui seal pole pÔhifaili index.html. Sellisel juhul tuleks kausta kompromiteerimise vÀltimiseks kasutada paketti .
Korralik sulgemine
Go-s on olemas ka selline funktsioon nagu HTTP-serveri korralik sulgemine. Seda saab teha Shutdown() meetodi abil. Server kĂ€ivitub goroutines ja seejĂ€rel kuulatakse signaali katkestamiseks. 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 on vĂ”imas keel, millel on quasi-ĂŒksne standardteek. Selle vaikimisi vĂ”imalused on ulatuslikud, ja neid saab tugevdada liideste abil â see vĂ”imaldab arendada tĂ”eliselt usaldusvÀÀrseid HTTP-servereid.
Skillbox soovitab:
- Kaks aastat praktilist kursust .
- Haridusalane veebikursus .
- Praktiline aastakursus .
Allikas: habr.com
