XNUMX幎åã«å§ããŸãã
ãã®èšäºã¯ Go ã§ã®ãµãŒããŒã®äœæã«é¢ããèšäºã§ãã ãHello world!ãã®ãããªåçŽãªãã®ããå§ããŠã次ã®æ©èœãæã€ã¢ããªã±ãŒã·ã§ã³ã§çµãããŸãããã
- HTTPS 㧠Let's Encrypt ã䜿çšããã
â API ã«ãŒã¿ãŒãšããŠæ©èœããŸãã
â ããã«ãŠã§ã¢ã®æäœã
â éçãã¡ã€ã«ã®åŠçã
â æ£ããã·ã£ããããŠã³ã
ã¹ãã«ããã¯ã¹ã¯æ¬¡ã®ããšãæšå¥šããŸãã å®è·µã³ãŒã¹
ããŒãããã®Pythonéçºè ã .ãªãã€ã³ããŒïŒ ãHabrãã®ãã¹ãŠã®èªè ã察象 - ãHabrãããã¢ãŒã·ã§ã³ ã³ãŒãã䜿çšããŠã¹ãã«ããã¯ã¹ ã³ãŒã¹ã«ç»é²ãããš 10 ã«ãŒãã«ã®å²åŒã
ããã«ã¡ã¯ãäžçïŒ
Go ã§ã¯ Web ãµãŒããŒãéåžžã«è¿ éã«äœæã§ããŸãã 以äžã¯ãäžã§çŽæãããHello, world!ããè¿ããã³ãã©ãŒã®äœ¿çšäŸã§ãã
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
})
http.ListenAndServe(":80", nil)
}
ãã®åŸãã¢ããªã±ãŒã·ã§ã³ãå®è¡ããŠããŒãžãéããšã
åŸã§ãã³ãã©ãŒãè€æ°å䜿çšããŸãããæåã«ãã¹ãŠãã©ã®ããã«æ©èœããããç解ããŸãããã
ããã/http
äŸã§ã¯ããã±ãŒãžã䜿çšããŸãã net/http
HTTPãã³ãã©ãŒ
ãªã¯ãšã¹ããåä¿¡ãããšããã³ãã©ãŒã¯ãããåæããå¿çãçæããŸãã Go ã®ãã³ãã©ãŒã¯æ¬¡ã®ããã«å®è£ ãããŸãã
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
æåã®äŸã§ã¯ãhttp.HandleFunc ãã«ããŒé¢æ°ã䜿çšããŸãã ããã¯å¥ã®é¢æ°ãã©ãããã次㫠http.ResponseWriter ãš http.Request ã ServeHTTP ã«åã蟌ã¿ãŸãã
èšãæããã°ãGolang ã®ãã³ãã©ãŒã¯åäžã®ã€ã³ã¿ãŒãã§ãŒã¹ã§è¡šç€ºãããããã°ã©ããŒã«å€ãã®ãªãã·ã§ã³ãæäŸããŸãã ãããã£ãŠãããšãã°ãããã«ãŠã§ã¢ã¯ãã³ãã©ãŒã䜿çšããŠå®è£ ãããŸãããã®ãã³ãã©ãŒã§ã¯ãServeHTTP ãæåã«äœããå®è¡ããŠãããå¥ã®ãã³ãã©ãŒã® ServeHTTP ã¡ãœãããåŒã³åºããŸãã
åè¿°ããããã«ããã³ãã©ãŒã¯ãªã¯ãšã¹ãã«å¯Ÿããå¿çãçæããã ãã§ãã ããããç¹å®ã®æç¹ã§ã©ã®ç¹å®ã®ãã³ãã©ãŒã䜿çšããå¿ èŠãããã®ã§ãããã?
ãªã¯ãšã¹ãã«ãŒãã£ã³ã°
æ£ããéžæãããã«ã¯ãHTTP ãã«ããã¬ã¯ãµãŒã䜿çšããŠãã ããã å€ãã®ã©ã€ãã©ãªã§ã¯ãã«ããã¬ã¯ãµãŒãŸãã¯ã«ãŒã¿ãŒãšåŒã°ããŠããŸããããããã¯ãã¹ãŠåããã®ã§ãã ãã«ããã¬ã¯ãµã®æ©èœã¯ããªã¯ãšã¹ã ãã¹ãåæããé©åãªãã³ãã©ãéžæããããšã§ãã
è€éãªã«ãŒãã£ã³ã°ã®ãµããŒããå¿
èŠãªå Žåã¯ããµãŒãããŒãã£ã®ã©ã€ãã©ãªã䜿çšããããšããå§ãããŸãã æãå
é²çãªãã®ã®ããã€ã -
éåžžã®ç¶æ³ã§è€éãªãã¬ãŒã ã¯ãŒã¯ã䜿çšããã«ã¯ãéæšæºã®ãœãªã¥ãŒã·ã§ã³ãå¿ èŠãšãªããããã«ããããã©ã«ãã®ãã³ãã©ãŒã®äœ¿çšãå€§å¹ ã«è€éã«ãªããŸãã 倧éšåã®ã¢ããªã±ãŒã·ã§ã³ãäœæããã«ã¯ãããã©ã«ãã®ã©ã€ãã©ãªãšåçŽãªã«ãŒã¿ãŒã®çµã¿åããã§ååã§ãã
ã¯ãšãªåŠç
ããã«ãåä¿¡æ¥ç¶ãããªãã¹ã³ããããã¹ãŠã®ãªã¯ãšã¹ããæ£ãããã³ãã©ãŒã«ãªãã€ã¬ã¯ãããã³ã³ããŒãã³ããå¿ èŠã§ãã http.Server ã¯ãã®ã¿ã¹ã¯ãç°¡åã«åŠçã§ããŸãã
以äžã¯ããµãŒããŒãæ¥ç¶åŠçã«é¢é£ãããã¹ãŠã®ã¿ã¹ã¯ãæ åœããããšã瀺ããŠããŸãã ããšãã°ããã㯠TLS ãããã³ã«ã䜿çšããŠæ©èœããŸãã http.ListenAndServer åŒã³åºããå®è£ ããã«ã¯ãæšæºã® HTTP ãµãŒããŒã䜿çšãããŸãã
次ã«ãããè€éãªäŸãèŠãŠã¿ãŸãããã
Let's Encrypt ã®è¿œå
ããã©ã«ãã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯ HTTP ãããã³ã«äžã§å®è¡ãããŸãããHTTPS ãããã³ã«ã䜿çšããããšããå§ãããŸãã ãã㯠Go ã§ã¯åé¡ãªãå®è¡ã§ããŸãã 蚌ææžãšç§å¯ããŒãåãåã£ãå Žåã¯ãæ£ãã蚌ææžãšã㌠ãã¡ã€ã«ã䜿çšã㊠ListenAndServeTLS ãç»é²ããã ãã§ååã§ãã
http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil)
ãã€ã§ãããè¯ããã®ãäœãããšãã§ããŸãã
autocert
.
ãããæ§æããæãç°¡åãªæ¹æ³ã¯ãautocert.NewListener ã¡ãœããã http.Serve ãšçµã¿åãããŠäœ¿çšââããããšã§ãã ãã®ã¡ãœããã䜿çšãããšãHTTP ãµãŒããŒããªã¯ãšã¹ããåŠçããŠããéã« TLS 蚌ææžãååŸããã³æŽæ°ã§ããŸãã
http.Serve(autocert.NewListener("example.com"), nil)
ãã©ãŠã¶ã§éããš
ãã詳现ãªæ§æãå¿ èŠãªå Žåã¯ãautocert.Manager ãããŒãžã£ãŒã䜿çšããå¿ èŠããããŸãã 次ã«ãç¬èªã® http.Server ã€ã³ã¹ã¿ã³ã¹ãäœæã (ãããŸã§ã¯ããã©ã«ãã§äœ¿çšããŠããŸãã)ããããŒãžã£ãŒã TLSConfig ãµãŒããŒã«è¿œå ããŸãã
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("", "")
ããã¯ã蚌ææžã®èªåæŽæ°ã«ããå®å šãª HTTPS ãµããŒããå®è£ ããç°¡åãªæ¹æ³ã§ãã
ã«ã¹ã¿ã ã«ãŒãã®è¿œå
æšæºã©ã€ãã©ãªã«å«ãŸããŠããããã©ã«ãã®ã«ãŒã¿ãŒã¯åªããŠããŸãããéåžžã«åºæ¬çãªãã®ã§ãã ã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã¹ããããã«ãŒããã¯ã€ã«ãã«ãŒã ã«ãŒãããŸãã¯ãã¹ ãã¿ãŒã³ãšãã©ã¡ãŒã¿ãèšå®ããæé ãªã©ãããè€éãªã«ãŒãã£ã³ã°ãå¿ èŠã§ãã
ãã®å Žåãããã±ãŒãžã䜿çšãã䟡å€ããããŸã
API ã®ã«ãŒããå«ããã¡ã€ã« api/v1/api.go ã瀺ããŸãã
/ 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
}
ã¡ã€ã³ãã¡ã€ã«ã®ã«ãŒãã« api/vq ãã¬ãã£ãã¯ã¹ãèšå®ããŸãã
次ã«ããããã¡ã€ã³ ã¢ããªã±ãŒã·ã§ã³ã® api/v1/ ãã¬ãã£ãã¯ã¹ã®äžã«ããã¡ã€ã³ ã«ãŒã¿ãŒã«ããŠã³ãããŸãã
// 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 ã¯è€éãªã«ãŒããæ±ããããããã倧èŠæš¡ã§è€éãªã¢ããªã±ãŒã·ã§ã³ã®æ§é ãšã¡ã³ããã³ã¹ãç°¡çŽ åã§ããŸãã
ããã«ãŠã§ã¢ã®æäœ
ã¹ããŒãžã³ã°ã«ã¯ããã HTTP ãã³ãã©ãŒãå¥ã® HTTP ãã³ãã©ãŒã§ã©ããããããšãå«ãŸããèªèšŒãå§çž®ããã®ã³ã°ãããã³ãã®ä»ã®ããã€ãã®æ©èœãè¿ éã«å®è¡ã§ããããã«ãªããŸãã
äŸãšããŠãhttp.Handler ã€ã³ã¿ãŒãã§ã€ã¹ãèŠãŠãããã䜿çšããŠãµãŒãã¹ ãŠãŒã¶ãŒãèªèšŒãããã³ãã©ãŒãäœæããŸãã
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)
})
}
ããã«ãŠã§ã¢æ©èœãæ¡åŒµã§ãããchi ãªã©ã®ãµãŒãããŒãã£è£œã«ãŒã¿ãŒããããŸãã
éçãã¡ã€ã«ã®æäœ
Go æšæºã©ã€ãã©ãªã«ã¯ãç»åãJavaScriptãCSS ãã¡ã€ã«ãªã©ã®éçã³ã³ãã³ããæäœããæ©èœãå«ãŸããŠããŸãã ãããã«ã¯ãhttp.FileServer é¢æ°ãéããŠã¢ã¯ã»ã¹ã§ããŸãã ç¹å®ã®ãã£ã¬ã¯ããªãããã¡ã€ã«ãæäŸãããã³ãã©ãŒãè¿ããŸãã
func NewRouter() http.Handler {
router := chi.NewRouter()
r.Get("/{name}", HelloName)
// ÐаÑÑÑПйка ÑазЎаÑО ÑÑаÑОÑеÑкОÑ
ÑайлПв
staticPath, _ := filepath.Abs("../../static/")
fs := http.FileServer(http.Dir(staticPath))
router.Handle("/*", fs)
return r
http.Dir ã¯ããã£ã¬ã¯ããªã«ã¡ã€ã³ã®index.html ãã¡ã€ã«ãå«ãŸããŠããªãå Žåããã£ã¬ã¯ããªã®å
容ã衚瀺ããããšãèŠããŠãã䟡å€ããããŸãã ãã®å Žåããã£ã¬ã¯ããªã䟵害ãããã®ãé²ãããã«ãããã±ãŒãžã䜿çšããå¿
èŠããããŸãã unindexed
æ£ããã·ã£ããããŠã³
Go ã«ã¯ãHTTP ãµãŒããŒã®æ£åžžãªã·ã£ããããŠã³ãšåŒã°ããæ©èœããããŸãã ãã㯠Shutdown() ã¡ãœããã䜿çšããŠå®è¡ã§ããŸãã ãµãŒããŒã¯ãŽã«ãŒãã³ã§èµ·åããããã£ãã«ããªãã¹ã³ãããŠå²ã蟌ã¿ä¿¡å·ãåä¿¡ããŸãã ä¿¡å·ãåä¿¡ãããšããã«ãµãŒããŒã®é»æºããªãã«ãªããŸãããããã«ã¯ãªãã«ãªããæ°ç§åŸã«ãªãã«ãªããŸãã
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)
çµè«ãšããŠ
Go ã¯ãã»ãŒæ®éçãªæšæºã©ã€ãã©ãªãåãã匷åãªèšèªã§ãã ãã®ããã©ã«ãã®æ©èœã¯éåžžã«å¹ åºããã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠæ¡åŒµã§ããŸããããã«ãããçã«ä¿¡é Œæ§ã®é«ã HTTP ãµãŒããŒãéçºã§ããŸãã
ã¹ãã«ããã¯ã¹ã¯æ¬¡ã®ããšãæšå¥šããŸãã
- XNUMX幎éã®å®è·µã³ãŒã¹
ãç§ã¯ããã®ãŠã§ãéçºè ã§ãã .- æè²ãªã³ã©ã€ã³ã³ãŒã¹
ãè·æ¥ Java éçºè ã .- å®è·µäžå¹Žã³ãŒã¹
ã0ããPROãŸã§ã®PHPéçºè ã .
åºæïŒ habr.com