Slide 1

Slide 1 text

1 (Pͷ&OIBODFE4FSWF.VY DIJ͔ΒҠߦͰ͖Δͷ͔ʁ (PϦϦʔεύʔςΟ !TPOBUBSEͦͳଠגࣜձࣾ4UBDL

Slide 2

Slide 2 text

2 (Pͷ&OBIBOHFE4FSWF.VYͱ͸ʁ w )551)BOEMFSࢦఆ࣌ʹ)551.FUIPEΛࢦఆͰ͖ΔΑ͏ʹͳͬͨ w 1BUI͔Β஋ΛऔಘͰ͖ΔΑ͏ʹͳͬͨ

Slide 3

Slide 3 text

3 (Pͷ&OBIBOHFE4FSWF.VYͱ͸ʁ w )551)BOEMFSࢦఆ࣌ʹ)551.FUIPEΛࢦఆͰ͖ΔΑ͏ʹͳͬͨ

Slide 4

Slide 4 text

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Ͱ͸ ͜͏͢Δ͔͠ͳ͔ͬͨ

Slide 5

Slide 5 text

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ϥΠϒϥϦͰ͸ɺ ઐ༻ͷϝιουΛར༻͢Δ

Slide 6

Slide 6 text

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Λύεͷઌ಄ʹࢦఆͰ͖Δ

Slide 7

Slide 7 text

7 (Pͷ&OBIBOHFE4FSWF.VYͱ͸ʁ w 1BUI͔Β஋ΛऔಘͰ͖ΔΑ͏ʹͳͬͨ

Slide 8

Slide 8 text

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ΑΓલ͸ɺࣗ෼Ͱ஋Λύʔε͢Δඞཁ͕͋ͬͨ

Slide 9

Slide 9 text

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ϥΠϒϥϦͰ͸ɺ͜ͷΑ͏ʹ࣮૷͢Δ͜ͱ͕Ͱ͖ͨ

Slide 10

Slide 10 text

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ͰऔಘՄೳʹͳͬͨ

Slide 11

Slide 11 text

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ͷऔಘ͕Մೳʹͳͬͨ

Slide 12

Slide 12 text

12 IUUQ4FSWF.VYʹඞཁͳ΋ͷ͸ἧͬͨʁ DIJ͔ΒҠߦͰ͖Δʁ

Slide 13

Slide 13 text

13 (Pͷ4FSWF.VYͱDIJͷҧ͍ w ϧʔςΟϯά൑ఆ৚݅ w DIJ͸׬શҰக w IUUQ4FSWF.VY͸લํҰக w (P͔Β͸1BUIͷ຤ඌʹ\^Λࢦఆʹ͢Δ͜ͱͰ׬શҰகʹͳΔ

Slide 14

Slide 14 text

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΁ҠߦՄೳ

Slide 15

Slide 15 text

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Ͱ͸ݫ͍͠Մೳੑ͕͋Δɻ

Slide 16

Slide 16 text

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) …. }

Slide 17

Slide 17 text

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Λ࢖͍ͬͯΔਓ΋ଟ͍͸ͣ

Slide 18

Slide 18 text

18 (Pͷ4FSWF.VYͱDIJͷҧ͍ w ͦ͜Ͱ࡞Γ·ͨ͠ʂ w (PͷIUUQ4FSWF.VYΛ࢖͍ͭͭɺDIJͱಉ༷ͳศརͳϧʔςΟϯάઃఆΛ࣮ݱ͢ ΔϥΠϒϥϦ

Slide 19

Slide 19 text

19

Slide 20

Slide 20 text

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*ʹޓ׵͕ ͋ΔΘ͚Ͱ͸͋Γ·ͤΜ

Slide 21

Slide 21 text

21

Slide 22

Slide 22 text

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͞ΜͷൃදͰʂ

Slide 23

Slide 23 text

23 ·ͱΊ w DIJ͔ΒҠߦͰ͖Δͷ͔ʁ w )551.FUIPEͷࢦఆͱ1BUI7BMVF͑͋͞Ε͹ྑ͍৔߹͸IUUQ4FSWF.VYʹҠߦͰ͖Δ w 1BUI7BMVFͷύλʔϯϚον͕ඞཁͳ৔߹͸ɺDIJΛར༻͢Δ w DIJͷதͰϋϯυϥ΍ϛυϧ΢ΣΞͷઃఆ͚͕ͩඞཁͳ৔߹͸NJDIJΛ࢖͏͜ͱͰ IUUQ4FSWF.VYʹҠߦͰ͖Δ

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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 }

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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