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

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

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for sonatard sonatard
March 18, 2024
660

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

Avatar for sonatard

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