Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Protocol-Oriented Programming in Networking

Yosuke Ishikawa
March 03, 2016
14k

Protocol-Oriented Programming in Networking

Yosuke Ishikawa

March 03, 2016
Tweet

Transcript

  1. OVERVIEW PROTOCOL-ORIENTED PROGRAMMING IN NETWORKING 1. Wrapping NSURLSession using protocols

    2. Generic programming on the protocols 3. Combination with RxSwift
  2. GOAL l e t r e q u e s

    t = R e q u e s t ( ) S e s s i o n . s e n d R e q u e s t ( r e q u e s t ) { r e s u l t i n / / r e s u l t : R e s u l t < R e q u e s t . R e s p o n s e , E r r o r > }
  3. GOAL l e t r e q u e s

    t = C r e a t e I s s u e R e q u e s t ( r e p o s i t o r y I D : 1 2 3 , t i t l e : " T e s t " ) S e s s i o n . s e n d R e q u e s t ( r e q u e s t ) { r e s u l t i n / / r e s u l t : R e s u l t < I s s u e , E r r o r > } l e t r e q u e s t = S e a r c h R e p o s i t o r i e s R e q u e s t ( q u e r y : " s w i f t " ) S e s s i o n . s e n d R e q u e s t ( r e q u e s t ) { r e s u l t i n / / r e s u l t : R e s u l t < P a g i n a t i o n R e s p o n s e < R e p o s i t o r y > , E r r o r > } The type of result changes depending on the request type
  4. WHY PROTOCOL? 1. To associate response type with request type

    2. To provide flexible default implementation
  5. WHY PROTOCOL? 1. To associate response type with request type

    2. To provide flexible default implementation
  6. ASSOCIATING RESPONSE TYPE WITH REQUEST TYPE p r o t

    o c o l R e q u e s t T y p e { t y p e a l i a s R e s p o n s e v a r b a s e U R L : N S U R L { g e t } v a r m e t h o d : H T T P M e t h o d { g e t } v a r p a t h : S t r i n g { g e t } v a r p a r a m e t e r s : [ S t r i n g : A n y O b j e c t ] { g e t } f u n c r e s p o n s e F r o m O b j e c t ( o b j e c t : A n y O b j e c t , U R L R e s p o n s e : N S H T T P U R L R e s p o n s e ) t h r o w s - > R e s p o n s e }
  7. ASSOCIATING RESPONSE TYPE WITH REQUEST TYPE c l a s

    s S e s s i o n { . . . f u n c s e n d R e q u e s t < R e q u e s t : R e q u e s t T y p e > ( r e q e u s t : R e q u e s t , h a n d l e r : R e s u l t < R e q u e s t . R e s p o n s e , E r r o r > - > V o i d ) { d o { l e t d a t a : N S D a t a = . . . l e t j s o n : A n y O b j e c t = . . . l e t r e s p o n s e = r e q u e s t . r e s p o n s e F r o m O b j e c t ( j s o n . . . ) h a n d l e r ( . S u c c e s s ( r e s p o n s e ) ) / / R e q u e s t . R e s p o n s e } c a t c h { h a n d l e r ( . F a i l u r e ( e r r o r ) ) } } }
  8. ASSOCIATING RESPONSE TYPE WITH REQUEST TYPE l e t r

    e q u e s t = C r e a t e I s s u e R e q u e s t ( r e p o s i t o r y I D : 1 2 3 , t i t l e : " T e s t " ) S e s s i o n . s e n d R e q u e s t ( r e q u e s t ) { r e s u l t i n / / r e s u l t : R e s u l t < I s s u e , E r r o r > } l e t r e q u e s t = S e a r c h R e p o s i t o r i e s R e q u e s t ( q u e r y : " s w i f t " ) S e s s i o n . s e n d R e q u e s t ( r e q u e s t ) { r e s u l t i n / / r e s u l t : R e s u l t < P a g i n a t i o n R e s p o n s e < R e p o s i t o r y > , E r r o r > } The type of result changes depending on the request type
  9. WHY PROTOCOL? 2. To provide flexible default implementation 1. To

    associate response type with request type
  10. PROVIDING DEFAULT IMPLEMENTATION PART 1: COMMON CONFIGURATIONS p r o

    t o c o l G i t H u b R e q u e s t T y p e : R e q u e s t T y p e { } e x t e n s i o n G i t H u b R e q u e s t T y p e { v a r b a s e U R L : N S U R L { r e t u r n N S U R L ( s t r i n g : " h t t p s : / / a p i . g i t h u b . c o m " ) ! } }
  11. PROVIDING DEFAULT IMPLEMENTATION PART 2: PROTOCOL FOR JSON DECODING s

    t r u c t S e a r c h R e p o s i t o r i e s R e q u e s t : G i t H u b R e q u e s t T y p e { f u n c r e s p o n s e F r o m O b j e c t ( o b j e c t : A n y O b j e c t , U R L R e s p o n s e : N S H T T P U R L R e s p o n s e ) t h r o w s - > R e s p o n s e { g u a r d l e t d i c t i o n a r i e s = o b j e c t a s ? [ [ S t r i n g : A n y O b j e c t ] ] e l s e { t h r o w I n v a l i d O b j e c t ( o b j e c t ) } l e t r e p o s i t o r i e s = d i c t i o n a r i e s . m a p { t r y R e p o s i t o r y ( $ 0 ) } l e t h a s N e x t P a g e = . . . r e t u r n P a g i n a t i o n R e s p o n s e ( e l e m e n t s : r e p o s i t o r i e s , h a s N e x t P a g e : h a s N e x t P a g e ) }
  12. PROVIDING DEFAULT IMPLEMENTATION PART 2: PROTOCOL FOR JSON DECODING p

    r o t o c o l D e c o d a b l e { s t a t i c f u n c d e c o d e ( o b j e c t : A n y O b j e c t ) t h r o w s - > S e l f }
  13. PROVIDING DEFAULT IMPLEMENTATION PART 2: PROTOCOL FOR JSON DECODING e

    x t e n s i o n R e q u e s t T y p e w h e r e R e s p o n s e : D e c o d a b l e { f u n c r e s p o n s e F r o m O b j e c t ( o b j e c t : A n y O b j e c t , U R L R e s p o n s e : N S H T T P U R L R e s p o n s e ) t h r o w s - > R e s p o n s e { r e t u r n R e s p o n s e . d e c o d e ( o b j e c t ) } }
  14. PROVIDING DEFAULT IMPLEMENTATION PART 2: PROTOCOL FOR JSON DECODING s

    t r u c t S e a r c h R e p o s i t o r i e s R e q u e s t : G i t H u b R e q u e s t T y p e { l e t q u e r y : S t r i n g / / M A R K : R e q u e s t T y p e t y p e a l i a s R e s p o n s e = P a g i n a t i o n R e s p o n s e < R e p o s i t o r y > v a r m e t h o d : H T T P M e t h o d { r e t u r n . G E T } v a r p a t h : S t r i n g { r e t u r n " / s e a r c h / r e p o s i t o r i e s " } v a r p a r a m e t e r s : A n y O b j e c t { r e t u r n [ " q " : q u e r y ] } }
  15. WHY PROTOCOL? 1. To associate response type with request type

    Simpler and safer call-site 2. To provide flexible default implementation Documentation-like request definition
  16. PAGINATION REQUEST c u r l - v h t

    t p s : / / a p i . g i t h u b . c o m / s e a r c h / r e p o s i t o r i e s ? q = s w i f t & p a g e = 1
  17. PAGINATION REQUEST p r o t o c o l

    P a g i n a t i o n R e q u e s t T y p e : R e q u e s t T y p e { t y p e a l i a s R e s p o n s e : P a g i n a t i o n R e s p o n s e T y p e v a r p a g e : I n t { g e t } f u n c r e q u e s t W i t h P a g e ( p a g e : I n t ) - > S e l f }
  18. PAGINATION RESPONSE H T T P / 1 . 1

    2 0 0 O K S e r v e r : G i t H u b . c o m C o n t e n t - T y p e : a p p l i c a t i o n / j s o n ; c h a r s e t = u t f - 8 L i n k : < h t t p s : / / a p i . g i t h u b . c o m / . . . > ; r e l = " n e x t " { " t o t a l _ c o u n t " : 3 8 2 6 2 , " i n c o m p l e t e _ r e s u l t s " : f a l s e , " i t e m s " : [ . . . ] }
  19. PAGINATION RESPONSE p r o t o c o l

    P a g i n a t i o n R e s p o n s e T y p e { t y p e a l i a s E l e m e n t : D e c o d a b l e v a r e l e m e n t s : [ E l e m e n t ] { g e t } v a r h a s N e x t P a g e : B o o l { g e t } }
  20. PAGINATION CLIENT c l a s s P a g

    i n a t i o n C l i e n t < R e q u e s t : P a g i n a t i o n R e q u e s t T y p e > { l e t b a s e R e q u e s t : R e q u e s t l e t u p d a t e H a n d l e r : V o i d - > V o i d i n i t ( b a s e R e q u e s t : R e q u e s t , u p d a t e H a n d l e r : V o i d - > V o i d ) { . . . } v a r e l e m e n t s : [ R e q u e s t . R e s p o n s e . E l e m e n t ] v a r h a s N e x t P a g e : B o o l v a r p a g e : I n t f u n c r e f r e s h ( ) { . . . } f u n c l o a d N e x t P a g e ( ) { . . . } }
  21. PAGINATION CLIENT f u n c r e f r

    e s h ( ) { l e t r e q u e s t = b a s e R e q u e s t . r e q u e s t W i t h P a g e ( 1 ) S e s s i o n . s e n d R e q u e s t ( r e q u e s t ) { r e s u l t i n s w i t c h r e s u l t { c a s e . S u c c e s s ( l e t r e s p o n s e ) : s e l f . p a g e = p a g e s e l f . e l e m e n t s = r e s p o n s e . e l e m e n t s s e l f . h a s N e x t P a g e = r e s p o n s e . h a s N e x t P a g e s e l f . u p d a t e H a n d l e r ( ) c a s e . F a i l u r e ( l e t e r r o r ) : / / h a n d l e e r r o r } } }
  22. PAGINATION VM WITH RXSWIFT c l a s s P

    a g i n a t i o n V i e w M o d e l < T : P a g i n a t i o n R e q u e s t T y p e > { i n i t ( b a s e R e q u e s t : T ) { . . . } / / I n p u t l e t r e f r e s h T r i g g e r : P u b l i s h S u b j e c t < V o i d > l e t n e x t P a g e T r i g g e r : P u b l i s h S u b j e c t < V o i d > / / O u t p u t l e t e l e m e n t s : O b s e r v a b l e < [ R e q u e s t . R e s p o n s e . E l e m e n t ] > l e t h a s N e x t P a g e : O b s e r v a b l e < B o o l > l e t l o a d i n g : O b s e r v a b l e < B o o l > }
  23. CONCLUSION PROTOCOL-ORIENTED IN NETWORKING 1. Protocol is a good choice

    for abstraction of networking 2. More type constraints, more detailed implementation 3. Abstraction of event stream is also nice