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
Redshift認可、アップデートでどう変わった?
handy
1
120
「アウトプット脳からユーザー価値脳へ」がそんなに簡単にできたら苦労しない #RSGT2026
aki_iinuma
6
1.7k
Autonomous Database - Dedicated 技術詳細 / adb-d_technical_detail_jp
oracle4engineer
PRO
5
12k
2025年のデザインシステムとAI 活用を振り返る
leveragestech
0
630
Oracle Cloud Infrastructure:2025年12月度サービス・アップデート
oracle4engineer
PRO
0
160
複雑さを受け入れるか、拒むか? - 事業成長とともに育ったモノリスを前に私が考えたこと #RSGT2026
murabayashi
0
700
2025年の医用画像AI/AI×medical_imaging_in_2025_generated_by_AI
tdys13
0
270
「リリースファースト」の実感を届けるには 〜停滞するチームに変化を起こすアプローチ〜 #RSGT2026
kintotechdev
0
330
マーケットプレイス版Oracle WebCenter Content For OCI
oracle4engineer
PRO
5
1.5k
モノタロウ x クリエーションラインで実現する チームトポロジーにおける プラットフォームチーム・ ストリームアラインドチームの 効果的なコラボレーション
creationline
0
140
AWS re:Inventre:cap ~AmazonNova 2 Omniのワークショップを体験してきた~
nrinetcom
PRO
0
120
さくらのクラウド開発ふりかえり2025
kazeburo
2
1.3k
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.9k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.3k
Between Models and Reality
mayunak
1
150
Thoughts on Productivity
jonyablonski
73
5k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
34
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
39
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
120
Heart Work Chapter 1 - Part 1
lfama
PRO
3
35k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
How to Talk to Developers About Accessibility
jct
1
93
Amusing Abliteration
ianozsvald
0
79
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