Slide 1

Slide 1 text

Go言語でAPIサーバーを実装しました 2018.02.24 Umeda.go #3 1 Gemcook エンジニア 岡本 洋輔

Slide 2

Slide 2 text

ࣗݾ঺հ ໊લɹ ॴଐ 2 BEFORE AFTER Ԭຊ༸ี PLBNPUPZPTVLF HDPLB (JUIVC HDPLB RJJUB ൒೥લ͔Βגࣜձࣾ(FNDPPL %PDLFS (PMBOH୲౰ ࢖༻ٕज़

Slide 3

Slide 3 text

ࠓ೔࿩͢͜ͱ (PͰ$UP$αʔϏεͷ"1*αʔόʔΛ࣮૷ͨ͠ߏ੒ ࠓճͷߏ੒Ͱྑ͔ͬͨͱ͜Ζ ࠔͬͨͱ͜Ζɺ௚͍ͨ͠ͱ͜Ζ 3

Slide 4

Slide 4 text

αʔϏεͷߏ੒ 4 Ϣʔβʔ؅ཧ ϑϩϯτΞϓϦ ܾࡁαʔϏε APIαʔόʔ σʔλϕʔε

Slide 5

Slide 5 text

APIαʔόʔʹ࢖͍ͬͯΔύοέʔδ 8"' 8FC"QQMJDBUJPO'SBNFXPSL w(JO 03Ϛούʔ w9PSN 5

Slide 6

Slide 6 text

WAF (Web Application Framework) w 3&45"1*αʔόʔΛ࡞ΔͷͰγϯϓϧͳ&DIP (JO *SJT͕ީิ w *SJT͕ྑͦ͞͏͕ͩɺίϛολʔͷྑ͘ͳ͍ᷚΛฉ͍ͯީิ͔Β֎ͨ͠ w &DIPͱ(JO͸(JUIVCελʔ਺ͱϕϯνɺϝϯςঢ়گ͔Β(JOΛબ୒ 6

Slide 7

Slide 7 text

Ginͷ࢖͍ํ w 1BUIύϥϝʔλͷݕূΛ.JEEMFXBSFʹͯ͠ɺDPOUSPMMFSͰ͸ OBNFD.VTU(FU lVTFSOBNFz TUSJOH ͱ͠ɺίϯτϩʔϥʔΛεϦϜԽ w HJOίϚϯυ IUUQTHJUIVCDPNDPEFHBOHTUBHJO ͰϥΠϒϦϩʔυ HPͰ࠶Ϗϧυ͕௒ߴ଎ʹ

Slide 8

Slide 8 text

O/R Ϛούʔ w (03. HPSQ 9PSN͕ީิ w HPSQ͸ϝϯςφϯε͕ࢭ·͍ͬͯΔͷͰީิ͔Β֎ͨ͠ w (03.ͱ9PSNͰ͸(03.ͷํ͕(JUIVCελʔ਺͕ଟ͍ w 9PSNͷํ͕γϯϓϧͳ"1*ͳͷͱɺຒΊࠐΈߏ଄ମରԠ͕ྑ͔ͬͨ 8

Slide 9

Slide 9 text

Xorm ຒΊࠐΈߏ଄ମͷྫ // User ユーザー情報を格納 type User struct { Common `xorm:"extends"` IdentityCode string `xorm:"notnull" json:”identity_code”` UserPublicData `xorm:"extends"` CustomerID string `xorm:"" json:"customer_id"` } // UserPublicData は公開⽤のユーザー情報を格納 type UserPublicData struct { PublicID uint64 `xorm:"-" json:"id"` UserProfile `xorm:"extends"` LastLoginAt *time.Time `json:"last_login_at"` } // Common テーブル共通項⽬を定義 type Common struct { ID uint64 `xorm:"pk autoincr index(pk)" json:"id"` IsDeleted bool `xorm:"default false notnull" json:"is_deleted"` CreatedAt *time.Time `xorm:"created notnull" json:"created_at"` UpdatedAt *time.Time `xorm:"updated notnull" json:"updated_at"` } ߏ଄ମʹڞ௨ߏ଄ମΛຒΊࠐΜͰޮ཰Α͘.PEFMͷఆ͕ٛग़དྷΔͱ͜Ζ͕ྑ͍ xorm:”extends”͸ json.MarshalͷΑ͏ʹ ຒΊࠐΈΛల։ͯ͘͠ΕΔ 9

Slide 10

Slide 10 text

ϨΠϠʔυϞσϧ ΫϦʔϯΞʔΩςΫνϟʔͱಉ͡ߏ੒ ϧʔςΟϯάɾɾɾ"1*ΤϯυϙΠϯτͷఆٛ ίϯτϩʔϥʔɾɾɾɹϋϯυϥʔͷ࣮૷ αʔϏεɾɾɾϏδωεϩδοΫͷ࣮૷ ϦϙδτϦɾɾɾϞσϧ΁ͷΞΫηε ϞσϧɾɾɾυϝΠϯͷσʔλදݱ Πϯϑϥɾɾɾ%#ɺܾࡁαʔϏε ґଘؔ܎ 10

Slide 11

Slide 11 text

ϨΠϠʔυϞσϧ ΫϦʔϯΞʔΩςΫνϟʔͱಉ͡ߏ੒ ϧʔςΟϯάɾɾɾ"1*ΤϯυϙΠϯτͷఆٛ ίϯτϩʔϥʔɾɾɾɹϋϯυϥʔͷ࣮૷ αʔϏεɾɾɾϏδωεϩδοΫͷ࣮૷ ϦϙδτϦɾɾɾϞσϧ΁ͷΞΫηε ϞσϧɾɾɾυϝΠϯͷσʔλදݱ Πϯϑϥɾɾɾ%#ɺܾࡁαʔϏε ґଘؔ܎ 11 ͜ͷ෦෼ͷ઀ଓʹ αʔϏεϨδετϦ Λ࢖ͬͯ޻෉

Slide 12

Slide 12 text

αʔϏεϨδετϦᶃ // RegistryInterface はサービスレジストリ type RegistryInterface interface { NewUser() UserInterface } // Registry はサービスレジストリの実装 type Registry struct { engine infra.EngineInterface } // NewRegistry は依存を注⼊してサービスレジストリを初期化 func NewRegistry(engine infra.EngineInterface) RegistryInterface { return &Registry{engine} } // NewUser はUserサービスを取得 func (r *Registry) NewUser() UserInterface { userRepo := model.NewUsersRepository(r.engine) return NewUser(userRepo) } 12 wαʔϏεϨδετϦ͸શͯͷαʔϏεΛऔಘ͢ΔΠϯλʔϑΣʔεΛ࣋ͭ

Slide 13

Slide 13 text

αʔϏεϨδετϦᶄ // ServiceRegistryMiddleware はサービスレジストリを提供 func ServiceRegistryMiddleware(registry service.RegistryInterface) gin.HandlerFunc { return func(c *gin.Context) { c.Set("service", registry) c.Next() } } func GetUserByID(c *gin.Context) { // サービスレジストリから使うサービスを取得 registry := c.MustGet("service").(service.RegistryInterface) userService := registry.NewUser() 13 w.JEEMFXBSFͰɹ$POUFYUʹϨδετϦΛొ࿥ w$POUSPMMFSͰ͸$POUFYU͔ΒϨδετϦΛऔಘ

Slide 14

Slide 14 text

αʔϏεϨδετϦͷϞοΫᶃ // Registry はServiceRegistryのモック実装です type Registry struct { service.RegistryInterface FakeUser service.UserInterface FakeShop service.ShopInterface FakeUserActivity service.UserActivityInterface FakeActivityLogger service.ActivityLoggerInterface // …略… } // NewUser はFakeUserを返す func (r *Registry) NewUser() service.UserInterface { return r.FakeUser } wςετิॿ༻ύοέʔδʹαʔϏεϨδετϦϞοΫΛ࣮૷͓ͯ͘͠

Slide 15

Slide 15 text

αʔϏεϨδετϦͷϞοΫᶄ // User はUserサービスのモック実装 type User struct { service.UserInterface FakeGetByID func(id uint64) (*model.UserPublicData, bool) } // GetByID はFakeGetByIDを呼び出す func (u *User) GetByID(id uint64) (*model.UserPublicData, bool) { return u.FakeGetByID(id) } wର৅ͷςετͰݺ͹ΕΔGVODͷΈࠩ͠ࠐΊΔ࡞Γ

Slide 16

Slide 16 text

ࠓճͷߏ੒Ͱྑ͔ͬͨͱ͜Ζ ಛผͳ޻෉ͳ͘(PΒ͘͠ॻ͚͹ɺ࣮૷ͨ͠ϓϩάϥϜ͕҆ఆͯ͠ಈ࡞͢Δ Ϣʔβʔ؅ཧɺܾࡁʹ͸ϚωʔδυαʔϏεΛ࢖ָ͕ͬͯͰ͖ͨ ϨΠϠʔͱґଘؔ܎Λ៉ྷʹ෼͚ͨͷͰςετ͸ඇৗʹ࡞Γ΍͍͢ 16

Slide 17

Slide 17 text

ࠔͬͨͱ͜Ζɺ௚͍ͨ͠ͱ͜Ζ UJNF/PX Ͱݱࡏ࣌ࠁΛऔಘ͍ͯ͠ΔͷͰɺςετͰ࣌ؒΛ֬ೝͮ͠Β͍ &$Ͱ࣮ߦ͍ͯ͠ΔͷͰɺ&$4'BSHBUFͷίϯςφϕʔεʹҠߦ͍ͨ͠ %PDLFS։ൃ؀ڥ͕EFQͷWFOEFSPSJHΛ࡞੒͢ΔڍಈͰ͏·͍͔͘ͳ͍ 17 WHPʹظ଴ʂ

Slide 18

Slide 18 text

Goݴޠ ✖ AWS ✖ ReactͰ։ൃ͢Δ஥ؒΛืूதʂ https://www.wantedly.com/companies/gemcook 18