Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Go言語でAPIサーバーを実装しました
Search
yoskeoka
February 24, 2018
Technology
7
2.7k
Go言語でAPIサーバーを実装しました
GoでCtoCサービスのAPIサーバーを実装した構成
今回の構成で良かったところ
困ったところ、直したいところ
yoskeoka
February 24, 2018
Tweet
Share
More Decks by yoskeoka
See All by yoskeoka
フロントエンドの変遷がもたらしたバックエンドの進化
yoskeokamoto
3
770
Other Decks in Technology
See All in Technology
DSPy入門
tomehirata
6
900
プロダクト開発と社内データ活用での、BI×AIの現在地 / Data_Findy
sansan_randd
1
830
窓口業務を生成AIにおまかせ!Bedrock Agent Coreで実現する自治体AIエージェント!
rayofhopejp
0
180
Playwrightで始めるUI自動テスト入門
devops_vtj
0
170
DMMの検索システムをSolrからElasticCloudに移行した話
hmaa_ryo
0
370
最近読んで良かった本 / Yokohama North Meetup #10
mktakuya
0
900
AWS 環境で GitLab Self-managed を試してみた/aws-gitlab-self-managed
emiki
0
180
アノテーション作業書作成のGood Practice
cierpa0905
PRO
1
410
LLM APIを2年間本番運用して苦労した話
ivry_presentationmaterials
10
8.5k
JAWS UG AI/ML #32 Amazon BedrockモデルのライフサイクルとEOL対応/How Amazon Bedrock Model Lifecycle Works
quiver
1
840
ubuntu-latest から ubuntu-slim へ移行しよう!コスト削減うれしい~!
asumikam
0
110
仕様駆動開発を実現する上流工程におけるAIエージェント活用
sergicalsix
11
5.9k
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Done Done
chrislema
186
16k
Code Review Best Practice
trishagee
72
19k
Raft: Consensus for Rubyists
vanstee
140
7.2k
Writing Fast Ruby
sferik
630
62k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.3k
Balancing Empowerment & Direction
lara
5
710
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The World Runs on Bad Software
bkeepers
PRO
72
11k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
We Have a Design System, Now What?
morganepeng
54
7.9k
Transcript
Go言語でAPIサーバーを実装しました 2018.02.24 Umeda.go #3 1 Gemcook エンジニア 岡本 洋輔
ࣗݾհ ໊લɹ ॴଐ 2 BEFORE AFTER Ԭຊ༸ี PLBNPUPZPTVLF HDPLB (JUIVC
HDPLB RJJUB લ͔Βגࣜձࣾ(FNDPPL %PDLFS (PMBOH୲ ༻ٕज़
ࠓ͢͜ͱ (PͰ$UP$αʔϏεͷ"1*αʔόʔΛ࣮ͨ͠ߏ ࠓճͷߏͰྑ͔ͬͨͱ͜Ζ ࠔͬͨͱ͜Ζɺ͍ͨ͠ͱ͜Ζ 3
αʔϏεͷߏ 4 Ϣʔβʔཧ ϑϩϯτΞϓϦ ܾࡁαʔϏε APIαʔόʔ σʔλϕʔε
APIαʔόʔʹ͍ͬͯΔύοέʔδ 8"' 8FC"QQMJDBUJPO'SBNFXPSL w(JO 03Ϛούʔ w9PSN 5
WAF (Web Application Framework) w 3&45"1*αʔόʔΛ࡞ΔͷͰγϯϓϧͳ&DIP (JO *SJT͕ީิ w *SJT͕ྑͦ͞͏͕ͩɺίϛολʔͷྑ͘ͳ͍ᷚΛฉ͍ͯީิ͔Β֎ͨ͠
w &DIPͱ(JO(JUIVCελʔͱϕϯνɺϝϯςঢ়گ͔Β(JOΛબ 6
Ginͷ͍ํ w 1BUIύϥϝʔλͷݕূΛ.JEEMFXBSFʹͯ͠ɺDPOUSPMMFSͰ OBNFD.VTU(FU lVTFSOBNFz TUSJOH ͱ͠ɺίϯτϩʔϥʔΛεϦϜԽ w HJOίϚϯυ
IUUQTHJUIVCDPNDPEFHBOHTUBHJO ͰϥΠϒϦϩʔυ HPͰ࠶Ϗϧυ͕ߴʹ
O/R Ϛούʔ w (03. HPSQ 9PSN͕ީิ w HPSQϝϯςφϯε͕ࢭ·͍ͬͯΔͷͰީิ͔Β֎ͨ͠ w (03.ͱ9PSNͰ(03.ͷํ͕(JUIVCελʔ͕ଟ͍
w 9PSNͷํ͕γϯϓϧͳ"1*ͳͷͱɺຒΊࠐΈߏମରԠ͕ྑ͔ͬͨ 8
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
ϨΠϠʔυϞσϧ ΫϦʔϯΞʔΩςΫνϟʔͱಉ͡ߏ ϧʔςΟϯάɾɾɾ"1*ΤϯυϙΠϯτͷఆٛ ίϯτϩʔϥʔɾɾɾɹϋϯυϥʔͷ࣮ αʔϏεɾɾɾϏδωεϩδοΫͷ࣮ ϦϙδτϦɾɾɾϞσϧͷΞΫηε ϞσϧɾɾɾυϝΠϯͷσʔλදݱ Πϯϑϥɾɾɾ%#ɺܾࡁαʔϏε ґଘؔ 10
ϨΠϠʔυϞσϧ ΫϦʔϯΞʔΩςΫνϟʔͱಉ͡ߏ ϧʔςΟϯάɾɾɾ"1*ΤϯυϙΠϯτͷఆٛ ίϯτϩʔϥʔɾɾɾɹϋϯυϥʔͷ࣮ αʔϏεɾɾɾϏδωεϩδοΫͷ࣮ ϦϙδτϦɾɾɾϞσϧͷΞΫηε ϞσϧɾɾɾυϝΠϯͷσʔλදݱ Πϯϑϥɾɾɾ%#ɺܾࡁαʔϏε ґଘؔ 11
͜ͷ෦ͷଓʹ αʔϏεϨδετϦ Λͬͯ
αʔϏεϨδετϦᶃ // 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αʔϏεϨδετϦશͯͷαʔϏεΛऔಘ͢ΔΠϯλʔϑΣʔεΛ࣋ͭ
αʔϏεϨδετϦᶄ // 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͔ΒϨδετϦΛऔಘ
αʔϏεϨδετϦͷϞοΫᶃ // 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ςετิॿ༻ύοέʔδʹαʔϏεϨδετϦϞοΫΛ࣮͓ͯ͘͠
αʔϏεϨδετϦͷϞοΫᶄ // 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ͷΈࠩ͠ࠐΊΔ࡞Γ
ࠓճͷߏͰྑ͔ͬͨͱ͜Ζ ಛผͳͳ͘(PΒ͘͠ॻ͚ɺ࣮ͨ͠ϓϩάϥϜ͕҆ఆͯ͠ಈ࡞͢Δ ϢʔβʔཧɺܾࡁʹϚωʔδυαʔϏεΛָ͕ͬͯͰ͖ͨ ϨΠϠʔͱґଘؔΛ៉ྷʹ͚ͨͷͰςετඇৗʹ࡞Γ͍͢ 16
ࠔͬͨͱ͜Ζɺ͍ͨ͠ͱ͜Ζ UJNF/PX Ͱݱࡏ࣌ࠁΛऔಘ͍ͯ͠ΔͷͰɺςετͰ࣌ؒΛ֬ೝͮ͠Β͍ &$Ͱ࣮ߦ͍ͯ͠ΔͷͰɺ&$4'BSHBUFͷίϯςφϕʔεʹҠߦ͍ͨ͠ %PDLFS։ൃڥ͕EFQͷWFOEFSPSJHΛ࡞͢ΔڍಈͰ͏·͍͔͘ͳ͍ 17 WHPʹظʂ
Goݴޠ ✖ AWS ✖ ReactͰ։ൃ͢ΔؒΛืूதʂ https://www.wantedly.com/companies/gemcook 18