Slide 1

Slide 1 text

HTTP API & Py Milan Čermák Pyvo Praha, 20. 2. 2013 Wednesday, February 20, 13

Slide 2

Slide 2 text

What makes a good API? Wednesday, February 20, 13

Slide 3

Slide 3 text

Wednesday, February 20, 13

Slide 4

Slide 4 text

Consistency Wednesday, February 20, 13

Slide 5

Slide 5 text

Consistency Predictability Wednesday, February 20, 13

Slide 6

Slide 6 text

Consistency Predictability Adherence to standards Wednesday, February 20, 13

Slide 7

Slide 7 text

Consistency Predictability Adherence to standards Great documentation Wednesday, February 20, 13

Slide 8

Slide 8 text

Why HTTP? Wednesday, February 20, 13

Slide 9

Slide 9 text

"While HTTP isn’t always the best answer, it’s a damn fine first guess." Coda Hale Wednesday, February 20, 13

Slide 10

Slide 10 text

Benefits of HTTP Wednesday, February 20, 13

Slide 11

Slide 11 text

Benefits of HTTP The most widespread application protocol Wednesday, February 20, 13

Slide 12

Slide 12 text

Benefits of HTTP The most widespread application protocol Statelessness Wednesday, February 20, 13

Slide 13

Slide 13 text

Benefits of HTTP The most widespread application protocol Statelessness Optional caching Wednesday, February 20, 13

Slide 14

Slide 14 text

Benefits of HTTP The most widespread application protocol Statelessness Optional caching Promotes layered infrastructure Wednesday, February 20, 13

Slide 15

Slide 15 text

Benefits of HTTP The most widespread application protocol Statelessness Optional caching Promotes layered infrastructure etc. Wednesday, February 20, 13

Slide 16

Slide 16 text

Limitations of HTTP Wednesday, February 20, 13

Slide 17

Slide 17 text

Limitations of HTTP Authorization Wednesday, February 20, 13

Slide 18

Slide 18 text

Limitations of HTTP Authorization Statelessness Wednesday, February 20, 13

Slide 19

Slide 19 text

Limitations of HTTP Authorization Statelessness Verbosity Wednesday, February 20, 13

Slide 20

Slide 20 text

Limitations of HTTP Authorization Statelessness Verbosity Crippled parallelism Wednesday, February 20, 13

Slide 21

Slide 21 text

"REST" if protocol.startswith("http") else "you're doing it wrong" Wednesday, February 20, 13

Slide 22

Slide 22 text

Set of architectural constraints Wednesday, February 20, 13

Slide 23

Slide 23 text

Set of architectural constraints Client-server Wednesday, February 20, 13

Slide 24

Slide 24 text

Set of architectural constraints Client-server Stateless Wednesday, February 20, 13

Slide 25

Slide 25 text

Set of architectural constraints Client-server Stateless Cacheable Wednesday, February 20, 13

Slide 26

Slide 26 text

Set of architectural constraints Client-server Stateless Cacheable Layered Wednesday, February 20, 13

Slide 27

Slide 27 text

Set of architectural constraints Client-server Stateless Cacheable Layered Uniform interface * Wednesday, February 20, 13

Slide 28

Slide 28 text

How can Python help? Wednesday, February 20, 13

Slide 29

Slide 29 text

OOP Wednesday, February 20, 13

Slide 30

Slide 30 text

OOP URI ~ Class handler mapping Wednesday, February 20, 13

Slide 31

Slide 31 text

import handlers urls = [(r"/user", handlers.users.NewUser), (r"/user/(\d+)", handlers.users.User)] class User(handler.base.BaseHandler): def delete(self, user_id): pass def get(self, user_id): pass def post(self, user_id): pass Wednesday, February 20, 13

Slide 32

Slide 32 text

class UserValidatorMixin(object): def check_user_data(self, user_dict): pass class User(handler.base.BaseHandler, UserValidatorMixin): def post(self, user_id): new_user = self.get_argument(“user”) if not self.check_user_data(new_user): return self.http_error(400, “Invalid data”) Wednesday, February 20, 13

Slide 33

Slide 33 text

Middleware Wednesday, February 20, 13

Slide 34

Slide 34 text

Wednesday, February 20, 13

Slide 35

Slide 35 text

Extending JSONEncoder Wednesday, February 20, 13

Slide 36

Slide 36 text

import json class AppJSONEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, User): return {"name": obj.name, "height": obj.height, "cash": obj.get_bank_account_balance()} return json.JSONEncoder.default(self, obj) user = User("1337") json.dumps(user, cls=AppJSONEncoder) Wednesday, February 20, 13

Slide 37

Slide 37 text

What about mobile? Wednesday, February 20, 13

Slide 38

Slide 38 text

Compression of HTTP bodies GET /user/1337 HTTP/1.1 Host: api.napyvo.io Accept-Encoding: gzip, identity Wednesday, February 20, 13

Slide 39

Slide 39 text

Compression of HTTP bodies HTTP/1.1 200 OK Content-Encoding: gzip Content-Type: application/json; charset=utf-8 Wednesday, February 20, 13

Slide 40

Slide 40 text

Compression of HTTP bodies POST /user HTTP/1.1 Host: api.napyvo.io Content-Encoding: gzip Content-Type: application/json [gzipped representation of a user] Wednesday, February 20, 13

Slide 41

Slide 41 text

Caching Cache-Control: max-age=3600 Expires: Thu, 31 Jan 2013 22:00:00 GMT <- Last-Modified: Thu, 31 Jan 2013 18:30:00 GMT -> If-Modified-Since: Wed, 30 Jan 2013 13:37:00 GMT ETag: foo If-None-Match: foo Wednesday, February 20, 13

Slide 42

Slide 42 text

Partial resources Wednesday, February 20, 13

Slide 43

Slide 43 text

GET /car/9 {"car": { "color": "red", "passengers": [ {"href": "/user/1337", "rel": "self"}] } } Wednesday, February 20, 13

Slide 44

Slide 44 text

GET /car/9?zoom=passengers {"car": { "color": "red", "passengers": [ {"href": "/user/1337", "rel": "self", "name": "Milan", "drink": "beer", "skills": ["python", "http"], }] } } Wednesday, February 20, 13

Slide 45

Slide 45 text

The promise of Hypermedia Wednesday, February 20, 13

Slide 46

Slide 46 text

Hypermedia as the engine of application state Wednesday, February 20, 13

Slide 47

Slide 47 text

Q & A Wednesday, February 20, 13