Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go 1.22のEnhanced ServeMux chiから移行できるのか?

sonatard
March 18, 2024
310

Go 1.22のEnhanced ServeMux chiから移行できるのか?

sonatard

March 18, 2024
Tweet

Transcript

  1. 4 )551)BOEMFSࢦఆ࣌ʹ)551.FUIPEΛࢦఆͰ͖ΔΑ͏ʹͳͬͨ h := func(w http.ResponseWriter, r *http.Request) { if

    r.Method != "GET" { w.WriteHeader(http.StatusMethodNotAllowed) w.Write([]byte("error")) return } w.Write([]byte("Hello, World!")) } mux := http.NewServeMux() mux.HandleFunc("/hello",h) (PΑΓલ͸ɺOFUIUUQQBDLBHFͰ͸ ͜͏͢Δ͔͠ͳ͔ͬͨ
  2. 5 )551)BOEMFSࢦఆ࣌ʹ)551.FUIPEΛࢦఆͰ͖ΔΑ͏ʹͳͬͨ h := func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello,

    World!")) } r := chi.NewRouter() r.Get("/hello",h) DIJͷΑ͏ͳSEQBSUZϥΠϒϥϦͰ͸ɺ ઐ༻ͷϝιουΛར༻͢Δ
  3. 6 )551)BOEMFSࢦఆ࣌ʹ)551.FUIPEΛࢦఆͰ͖ΔΑ͏ʹͳͬͨ h := func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello,

    World!")) } mux := http.NewServeMux() mux.HandleFunc("GET /hello",h) (PҎ߱͸ɺ)551.FUIPEΛύεͷઌ಄ʹࢦఆͰ͖Δ
  4. 8 1BUI͔Β஋ΛऔಘͰ͖ΔΑ͏ʹͳͬͨ h := func(w http.ResponseWriter, r *http.Request) { userID

    := strings.TrimPrefix(r.URL.Path, "/user/") w.Write([]byte(userID)) } mux := http.NewServeMux() mux.HandleFunc("/user/",h) (PΑΓલ͸ɺࣗ෼Ͱ஋Λύʔε͢Δඞཁ͕͋ͬͨ
  5. 9 1BUI͔Β஋ΛऔಘͰ͖ΔΑ͏ʹͳͬͨ h := func(w http.ResponseWriter, r *http.Request) { userID

    := chi.URLParam(r,"id") w.Write([]byte(userID)) } r := chi.NewRouter() r.HandleFunc("/user/{id}",h) DIJͷΑ͏ͳSEQBSUZϥΠϒϥϦͰ͸ɺ͜ͷΑ͏ʹ࣮૷͢Δ͜ͱ͕Ͱ͖ͨ
  6. 10 1BUI͔Β஋ΛऔಘͰ͖ΔΑ͏ʹͳͬͨ h := func(w http.ResponseWriter, r *http.Request) { userID

    := r.PathValue("id") w.Write([]byte(userID)) } mux := http.NewServeMux() mux.HandleFunc("/user/{id}",h) (PҎ߱͸ɺS1BUI7BMVFͰऔಘՄೳʹͳͬͨ
  7. 11 DIJ΋(Pͷ4FSWF.VYʹ߹ΘͤͯରԠ h := func(w http.ResponseWriter, r *http.Request) { userID

    := r.PathValue("id") w.Write([]byte(userID)) } r := chi.NewRouter() r.HandleFunc("GET /user/{id}",h) DIJWҎ߱͸ɺ(Pͱಉ͡ํ๏Ͱ )551.FUIPEͷࢦఆͱ1BUI7BMVFͷऔಘ͕Մೳʹͳͬͨ
  8. 14 (Pͷ4FSWF.VYͱDIJͷҧ͍ w Bʹ)BOEMFSΛొ࿥ͯ͠ɺBCʹϦΫΤετΛૹͬͨ৔߹ w IUUQ4FSWF.VY͸Bͷ)BOEMFSΛ࣮ߦ͠·͢ɻ w લํҰகͰBC͸BʹϚον͠·͢ɻ w DIJ͸/PU'PVOEΛฦ͠·͢ɻ

    w ׬શҰகͰBC͸BʹϚον͠·ͤΜɻ w B\^ʹ)BOEMFSΛొ࿥ͯ͠ɺBCʹϦΫΤετΛૹͬͨ৔߹ w IUUQ4FSWF.VYͰ/PU'PVOEʹͳΓ·͢ɻ w ׬શҰகͰBC͸BʹϚον͠·ͤΜɻ w \^ͰDIJͱಉ͡ৼΔ෣͍Λ࣮ݱͰ͖ΔͷͰɺIUUQ4FSFWF.VY΁ҠߦՄೳ
  9. 15 (Pͷ4FSWF.VYͱDIJͷҧ͍ w 7BMVFͷύλʔϯϚον w DIJ͸ҎԼͷΑ͏ʹύλʔϯΛࢦఆͰ͖·͢ɻIUUQ4FSWF.VYͰ͸Ͱ͖·ͤΜɻ w ਖ਼نදݱ w AEBUF\ZZZZaaEaaEaaEaaE^\NNaaEaaE^\EEaaEaaE^A

    w AEBUFA w ෦෼Ұக w AVTFS\VTFS*%^A w AVTFSA w ෳ਺ͷ7BMVF w A\ZZZZ^\NN^\EE^A w AA w ݸਓతʹ͸ɺ(SBQI2-Ͱ͋ΔͨΊ7BMVFͷύλʔϯϚονΛ࢖͏ػձ͸ͳ͍ͷͰɺ IUUQ4FSWF.VY΁ҠߦͰ͖Δɻ3&45Ͱ͸ݫ͍͠Մೳੑ͕͋Δɻ
  10. 16 (Pͷ4FSWF.VYͱDIJͷҧ͍ w ϧʔςΟϯά΍ϛυϧ΢ΣΞͷઃఆํ๏ type Router interface { … Use(middlewares

    ...func(http.Handler) http.Handler) With(middlewares ...func(http.Handler) http.Handler) Router Group(fn func(r Router)) Router Route(pattern string, fn func(r Router)) Router Handle(pattern string, h http.Handler) HandleFunc(pattern string, h http.HandlerFunc) …. }
  11. 17 (Pͷ4FSWF.VYͱDIJͷҧ͍ w ϧʔςΟϯά΍ϛυϧ΢ΣΞͷઃఆํ๏ r := chi.NewRouter() // UseʹΑΔϛυϧ΢ΣΞͷઃఆ r.Use(middleware.Logger)

    // RouteʹΑΔωετ r.Route("/articles", func(r chi.Router) { // WithʹΑΔϛυϧ΢ΣΞͷઃఆ r.With(paginate).HandleFunc("GET /", listArticles) r.HandleFunc("POST /", createArticle) r.HandleFunc("GET /search", searchArticles) r.Route("/{articleID}", func(r chi.Router) { r.Use(ArticleCtx) r.HandleFunc("GET /", getArticle) r.HandleFunc("PUT /", updateArticle) }) }) ͜Ε͕ศརͰDIJΛ࢖͍ͬͯΔਓ΋ଟ͍͸ͣ
  12. 19

  13. 20 NJDIJͱ͸ w NJDIJIUUQTHJUIVCDPNHPNJDIJNJDIJ w IUUQ4FSWF.VY΁ͷޓ׵͕͋Δ)551ϧʔλʔ w ϧʔςΟϯάͷػೳ͸׬શʹIUUQ4FSWF.VY΁ҕৡͯ͠ɺొ࿥ॲཧͷ࣮૷͚ͩΛ࣋ͭɻ r :=

    michi.NewRouter() // UseʹΑΔϛυϧ΢ΣΞͷઃఆ r.Use(middleware.Logger) // RouteʹΑΔωετ r.Route("/articles", func(r *michi.Router) { // WithʹΑΔϛυϧ΢ΣΞͷઃఆ r.With(paginate).HandleFunc("GET /", listArticles) r.HandleFunc("POST /", createArticle) r.HandleFunc("GET /search", searchArticles) r.Route("/{articleID}", func(r *michi.Router) { r.Use(ArticleCtx) r.HandleFunc("GET /", getArticle) r.HandleFunc("PUT /", updateArticle) }) }) DIJ3PVUFSΛ NJDIJ3PVUFSʹ ஔ͖׵͑Δ͜ͱͰ࢖͑·͢ ͢΂ͯͷ"1*ʹޓ׵͕ ͋ΔΘ͚Ͱ͸͋Γ·ͤΜ
  14. 21

  15. 22 NJDIJͷಛ௃ w ϧʔςΟϯά͸IUUQ4FSWF.VYͱͷޓ׵ੑ w IUUQ4FSWFS.VY IUUQ)BOEMFSBOEIUUQ)BOEMFS'VOD w &OIBODFEIUUQ4FSWF.VY w

    )551.FUIPEͷࢦఆͱ1BUI7BMVFͷऔಘ w DIJͷΑ͏ͳΠϯλʔϑΣʔε w 3PVUF (SPVQ 8JUIBOEDIJNJEEMFXBSFT w .JEEMFXBSFͷΠϯλʔϑΣʔε͕ಉ͡ͳͷͰɺDIJͷػೳʹґଘ͍ͯ͠ͳ͚Ε͹ɺDIJ͕ఏڙ͠ ͍ͯΔNJEEMFXBSF͕ར༻ՄೳͰ͢ w ֎෦ύοέʔδ΁ͷґଘ͸͋Γ·ͤΜ w ඪ४QBDLBHFͷΈΛར༻͍ͯ͠·͢ w ܰྔ w ίʔυ͸໿ߦͰ͢ɻ w ύϑΥʔϚϯε w NJDIJͱIUUQ4FSWF.VY͸ಉ౳ͷύϑΥʔϚϯεͰ͢ w IUUQ4FSWF.VY͸ߴ଎ʁɹ࣍ͷ5BLFEB͞ΜͷൃදͰʂ
  16. 24 ͓·͚ϧʔςΟϯάͰؾΛ͚ͭΔϙΠϯτ w Bʹొ࿥ͯ͠ɺBʹϦΫΤετΛૹ৴͢Δ w 3FEJSFDU r := http.NewServeMux() h:=

    func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, World!")) } r.HandleFunc("/a/", h) w := httptest.NewRecorder() req := httptest.NewRequest("", "/a", nil) r.ServeHTTP(w, req) fmt.Println(w.Result().StatusCode) // 301
  17. 25 ͓·͚ϧʔςΟϯάͰؾΛ͚ͭΔϙΠϯτ w Bʹొ࿥ͯ͠ɺBʹϦΫΤετΛૹ৴͢Δ w /PU'PVOE r := http.NewServeMux() h:=

    func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, World!")) } r.HandleFunc("/a", h) w := httptest.NewRecorder() req := httptest.NewRequest("", "/a/", nil) r.ServeHTTP(w, req) fmt.Println(w.Result().StatusCode) // 404 }
  18. 26 ͓·͚ϧʔςΟϯάͰؾΛ͚ͭΔϙΠϯτ w BͱB྆ํʹϋϯυϥΛొ࿥͠ͳ͍ͱ૝ఆͨ͠ڍಈʹͳΒͳ͍ʁ w ରԠࡦ w Bʹొ࿥͠ɺNJEEMFXBSFͰϦΫΤετͷ຤ඌΛ࡟আ w B

    w BNJEEMFXBSFͰ຤ඌͷ࡟আB r := michi.NewRouter() h:= func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, World!")) } r.Use(middleware.StripSlashes) r.HandleFunc("/a", h) w := httptest.NewRecorder() req := httptest.NewRequest("", "/a/", nil) r.ServeHTTP(w, req) fmt.Println(w.Result().StatusCode) // 200
  19. 27 ͓·͚ϧʔςΟϯάͰؾΛ͚ͭΔϙΠϯτ w ϛυϧ΢ΣΞͷ࣮ߦ w BDʹϦΫΤετ͢ΔͱBʹରͯ͠લํҰகͰNJEEMFXBSFͱϋϯυϥ͕࣮ߦ͞ΕΔ r.Route("/a", func(r *michi.Router) {

    r.Use(m("m")) r.HandleFunc("/", h("a")) r.HandleFunc("/b", h("b")) }) w := httptest.NewRecorder() req := httptest.NewRequest("", "/a/c", nil) // Status Code 200 // ma
  20. 28 ͓·͚ϧʔςΟϯάͰؾΛ͚ͭΔϙΠϯτ w ϛυϧ΢ΣΞͷ࣮ߦ w BDʹϦΫΤετ͢ΔͱલํҰகͰNJEEMFXBSFΛ࣮ߦɺϋϯυϥ͸\^ʹΑΓ׬શҰ கʹͳ͍ͬͯΔͷͰ࣮ߦ͞Εͳ͍ r.Route("/a", func(r *michi.Router)

    { r.Use(m("m")) r.HandleFunc(“/{$}”, h("a")) r.HandleFunc("/b", h("b")) }) w := httptest.NewRecorder() req := httptest.NewRequest("", "/a/c", nil) // Status Code 404 // m