Slide 1

Slide 1 text

PROTOCOL-ORIENTED PROGRAMMING IN NETWORKING ISHKAWA

Slide 2

Slide 2 text

ISHKAWA?

Slide 3

Slide 3 text

OVERVIEW PROTOCOL-ORIENTED PROGRAMMING IN NETWORKING 1. Wrapping NSURLSession using protocols 2. Generic programming on the protocols 3. Combination with RxSwift

Slide 4

Slide 4 text

TOPIC 1 Wrapping NSURLSession using protocols To make call-site code simpler To get responses type-safely

Slide 5

Slide 5 text

GOAL

Slide 6

Slide 6 text

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 > }

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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 }

Slide 11

Slide 11 text

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 ) ) } } }

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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 " ) ! } }

Slide 15

Slide 15 text

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 ) }

Slide 16

Slide 16 text

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 }

Slide 17

Slide 17 text

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 ) } }

Slide 18

Slide 18 text

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 ] } }

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

LINKS APIKit: RequestType, Session, etc. Himotoki: Decodable, etc. https://github.com/ishkawa/APIKit https://github.com/ikesyo/Himotoki

Slide 21

Slide 21 text

TOPIC 2 Practical example of generic programming on protocols Example: Pagination

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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 }

Slide 24

Slide 24 text

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 " : [ . . . ] }

Slide 25

Slide 25 text

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 } }

Slide 26

Slide 26 text

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 ( ) { . . . } }

Slide 27

Slide 27 text

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 } } }

Slide 28

Slide 28 text

GENERIC PROGRAMMING ON PROTOCOLS More type constraints, more detailed implementation

Slide 29

Slide 29 text

TOPIC 3 Advanced example with reactive streams

Slide 30

Slide 30 text

RXPAGINATION

Slide 31

Slide 31 text

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 > }

Slide 32

Slide 32 text

LIVE!

Slide 33

Slide 33 text

STEPS TO IMPLEMENT PAGINATION Give a base request to ViewModel Bind input and output streams

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

TRY! POP