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
760
Other Decks in Technology
See All in Technology
AWSの新機能検証をやる時こそ、Amazon Qでプロンプトエンジニアリングを駆使しよう
duelist2020jp
1
330
新卒エンジニアがCICDをモダナイズしてみた話
akashi_sn
2
280
Dataverseの検索列について
miyakemito
1
160
AI駆動で進化する開発プロセス ~クラスメソッドでの実践と成功事例~ / aidd-in-classmethod
tomoki10
1
640
SnowflakeとDatabricks両方でRAGを構築してみた
kameitomohiro
1
550
QA/SDETの現在と、これからの挑戦
imtnd
0
200
Microsoft Fabric vs Databricks vs (Snowflake) -若手エンジニアがそれぞれの強みと違いを比較してみた- "A Young Engineer's Comparison of Their Strengths and Differences"
reireireijinjin6
1
130
SREからゼロイチプロダクト開発へ ー越境する打席の立ち方と期待への応え方ー / Product Engineering Night #8
itkq
2
1.1k
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
7
63k
10分で学ぶ、RAGの仕組みと実践
supermarimobros
0
200
genspark_presentation.pdf
haruki_uiru
0
110
Winning at PHP in Production in 2025
beberlei
1
260
Featured
See All Featured
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
47
2.7k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
105
19k
The World Runs on Bad Software
bkeepers
PRO
68
11k
Optimising Largest Contentful Paint
csswizardry
37
3.2k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Writing Fast Ruby
sferik
628
61k
Facilitating Awesome Meetings
lara
54
6.3k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
19
1.2k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
770
It's Worth the Effort
3n
184
28k
VelocityConf: Rendering Performance Case Studies
addyosmani
329
24k
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