/ s a m p l e / g e t P O S T / v 1 / s a m p l e / c r e a t e P O S T / v 1 / s a m p l e / u p d a t e P O S T / v 1 / s a m p l e / d e l e t e P O S T / v 1 / s a m p l e / n a m e / u p d a t e G E T / v 1 / c h a r a c t e r / g e t G E T / v 1 / l o g i n _ c h a r a c t e r / g e t HTTP メソッドはPOST とGET のみ GET 不要説も リソー ス名/ 動詞 をエンドポイントとしてルー ティング ネストもOK 22
V 1 m o d u l e S a m p l e c l a s s G e t C o n t r o l l e r r e s c u e _ f r o m ( A c t i v e R e c o r d : : R e c o r d N o t F o u n d ) d o r e n d e r _ e r r o r ( : r e c o r d _ n o t _ f o u n d ) e n d d e f s e r v i c e s a m p l e = S a m p l e . f i n d ( p a r a m s [ : c h a r a c t e r _ i d ] ) r e n d e r _ a p i ( s a m p l e : s a m p l e ) e n d e n d e n d e n d コントロー ラはルー ティングと1 1 コントロー ラはservice アクションだけを持つという規約 render_api, render_error などrender をラップした専用メソッドでレ スポンスを送る 23
T / v 1 / l o g i n _ c h a r a c t e r みたいなのが大量に作られる とある場面でだけ必要なオー ルインワンな取得系API 開発中は要件が変わりやすいので柔軟に対応する必要がある 仕様変更時にURL が変わらなくても良いようにしたい… Unity 側(WWW クラス) の仕様の問題 POST とGET にしか対応してなかった GET 時のクエリストリングを自前で組み立てる必要があった Unity5.4 から提供されるUnityWebRequest クラスでかなりマ シにはなった 24
l e _ c r e a t e ) { u r l ' / s a m p l e / c r e a t e ' m e t h o d ' P O S T ' d e s c r i p t i o n ' サンプルを作るよ' e r r o r s { i t e m : r e c o r d _ n o t _ u n i q u e , ' 名前が重複したよ' } r e q u e s t { p a r a m ' n a m e ' , : s t r i n g , ' 素敵な名前' } r e s p o n s e { p a r a m ' s a m p l e ' , : s a m p l e , ' 作成したさんぷる' } } 29
p l e _ c r e a t e ) { u r l ' / s a m p l e / c r e a t e ' # U R L のエンドポイントを指定 m e t h o d ' P O S T ' # H T T P M e t h o d を指定 d e s c r i p t i o n ' サンプルを作るよ' # R P C の説明 } R a i l s . a p p l i c a t i o n . r o u t e s . d r a w d o n a m e s p a c e : v 1 d o n a m e s p a c e : s a m p l e d o n a m e s p a c e : c r e a t e d o m a t c h ' c r e a t e ' , c o n t r o l l e r : : c r e a t e , a c t i o n : : s e r v i c e , v i a : : p o s t e n d e n d e n d e n d 30
p l e _ c r e a t e ) { e r r o r s { # エラー の名前と説明 i t e m : r e c o r d _ n o t _ u n i q u e , ' 名前が重複したよ' } } m o d u l e S a m p l e m o d u l e C r e a t e m o d u l e E r r o r # e r r o r _ c o d e : 1 0 0 1 # d e s c r i p t i o n : 名前が重複したよ c l a s s R e c o r d N o t U n i q u e < : : R p c E r r o r : : R p c E r r o r B a s e d e f s e l f . e r r o r _ c o d e 1 0 0 1 e n d e n d e n d e n d e n d 31
m p l e _ c r e a t e ) { # リクエストの定義 r e q u e s t { # キー 名、 型、 説明 p a r a m ' n a m e ' , : s t r i n g , ' 素敵な名前' } # レスポンスの定義 r e s p o n s e { p a r a m ' s a m p l e ' , : s a m p l e , ' 作成したさんぷる' } } c l a s s R e q u e s t T y p e < T y p e : : B a s e a t t r i b u t e : n a m e , S t r i n g e n d c l a s s R e s p o n s e T y p e < T y p e : : B a s e a t t r i b u t e : s a m p l e , T y p e : : S a m p l e e n d 32
s a m p l e ) { p a r a m ' i d ' , : i n t , ' I D ' p a r a m ' n a m e ' , : s t r i n g , ' 名前' } r p c ( : s a m p l e _ c r e a t e ) { r e s p o n s e { # 利用例 p a r a m ' s a m p l e ' , : s a m p l e , ' 作成したさんぷる' } } c l a s s T y p e : : S a m p l e < T y p e : : B a s e a t t r i b u t e : i d , I n t e g e r a t t r i b u t e : n a m e , S t r i n g e n d c l a s s R e s p o n s e T y p e < T y p e : : B a s e a t t r i b u t e : s a m p l e , T y p e : : S a m p l e e n d 33
s # パラメー タの検証を行い、 失敗したらエラー を発生させる # S t r o n g P a r a m e t e r とは違い、 型など厳密なチェックを行なう R e q u e s t T y p e . n e w ( s u p e r ) e n d d e f s e r v i c e s a m p l e = S a m p l e . c r e a t e ! ( n a m e : p a r a m s [ : n a m e ] ) r e n d e r _ a p i ( s a m p l e : T y p e : : S a m p l e . n e w ( i d : s a m p l e . i d , n a m e : s a m p l e . n a m e ) ) e n d 36
r _ a p i ( r e s p o n s e ) # パラメー タの検証を行い、 失敗したらエラー を発生させる b o d y = R e s p o n s e T y p e . n e w ( r e s p o n s e ) r e s p o n d _ t o d o | f o r m a t | f o r m a t . m s g p a c k d o r e n d e r ( c o n t e n t _ t y p e : ' a p p l i c a t i o n / x ‐ m s g p a c k ' , b o d y : b o d y . t o _ m s g p a c k ) e n d # 開発時のみJ S O N を許可する事もできる f o r m a t . j s o n d o r e n d e r j s o n : b o d y . t o _ j s o n e n d i f R a i l s . d e v e l o p m e n t ? e n d e n d 37
o i d S e n d S a m p l e C r e a t e R e q u e s t ( s t r i n g n a m e ) { S a m p l e C r e a t e R e q u e s t r e q u e s t = n e w S a m p l e C r e a t e R e q u e s t ( ) ; r e q u e s t . n a m e = n a m e ; / / U R L , メソッドなどがラップされた、 自動生成されるクラス S a m p l e C r e a t e a p i = n e w S a m p l e C r e a t e ( r e q u e s t ) ; / / コー ルバックの登録 a p i . o n C o m p l e t e = O n S a m p l e C r e a t e C o m p l e t e ; a p i . o n E r r o r = O n S a m p l e C r e a t e E r r o r ; W e b R e q u e s t e r . R e q u e s t ( a p i ) } 38
s a m p l e ) { p a r a m : i d , : i n t 6 4 } c l a s s T y p e : : S a m p l e a t t r i b u t e : i d , I n t e g e r # r u b y 側はI n t e g e r として扱う e n d c l a s s S a m p l e { p u b l i c l o n g i d ; / / C # 側はl o n g として扱う } s t r u c t S a m p l e { i n t 6 4 _ t i d ; / / C + + 側はi n t 6 4 として扱う } 39