Download - Ep2014 hypermedia APIs
Cutting-Edge APIs Using Hypermedia at BSkyB
Adriana Vasiu [email protected]
Cutting-Edge APIs Using Hypermedia at BSkyB
The Sky Sales PlatformNew platform for delivering the Sky Sales Platform
Java Ruby Js Python
Hypermedia APIs
Distributed platform
What does ‘Hypermedia API’ mean?
Properties Performance
Scalability Simplicity Portability
etc.
Constraints Client-Server
Stateless Cache
Uniform Interface etc.
REST
Can an API be as easy as a Google search?
+ hypermedia controls change the whole application state
!
+ hypermedia makes use of the semantics of the links
!
+ a hypermedia API guides the clients through business processes
Hypermedia = REST ++
Advantages
Loose coupling !
Great platform for modelling business-to-business interactions
!
Simple approach for distributed application
development
Example – Pet Shop
Pet Shop Example
flask
HAL + JSON
restnavigatordougrain
!@pet_shop.route('/basket', methods=['POST']) !@pet_shop.route('/basket/<id>', methods=['GET', 'DELETE']) !@pet_shop.route('/pets/', methods=['GET']) !@pet_shop.route('/pets/<type>', methods=['GET']) !@pet_shop.route('/basket/<id>/pets/<pet_type>', methods=['POST', 'DELETE'])
What do clients need to know?
the host name the url to create the basket the url to get the pets the url to add/remove pets to basket what type a pet can be
RESTful Pet Shop API
The root of the Pet Shop API
the host name so they can get the API root
What do clients need to know?
!
Content-type: application/hal+json … !{ "name": "ep2014talk", "description": "this is a hal+json api", "_links": { "basket": { "href": "/basket", "method": "POST" } } }
With Hypermedia we only need to know the root URI!!
!
>>> >>> from restnavigator import HALNavigator >>> navigator = HALNavigator("http://europythontalk.ep2014.com/", apiname="ep2014talk") >>> >>> navigator.fetch() {u'name': u'ep2014talk', u'description': u'this is a hal+json api’} >>> >>> navigator.links {u'basket': HALNavigator(ep2014talk.basket)} >>> … !!!!
Create the basket!
!
!
>>> … >>> navigator.links {u'basket': HALNavigator(ep2014talk.basket)} >>> … >>> basket = navigator.links[‘basket’].create({}) >>> >>> basket.fetch() {u'id': u'53c2a9f5fcb82e54c5d7a3a3'} >>> >>> basket.links {u'pet': [HALNavigator(ep2014talk.basket.53c2a9f5fcb82e54c5d7a3a3.pets.cat)]} >>> … !
Basket created
!Content-type: application/hal+json … !{ "id": "53c2a9f5fcb82e54c5d7a3a3", "_links": { "pet": [ { "href": "/basket/53c2a9f5fcb82e54c5d7a3a3/pets/cat", "method": "GET" } ] } } !!!
Follow the “pet” link!
!
!
>>> … >>> basket.links {u'pet': [HALNavigator(eptalk.basket.53c2a9f5fcb82e54c5d7a3a3.pets.cat)]} >>> >>> pet = basket.links[‘pet’][0] >>> >>> pet.fetch() {u'type': u'cat', u'quantity': 0} >>> >>> pet.links {u'add': HALNavigator(eptalk.basket.53c2a9f5fcb82e54c5d7a3a3.pets.cat)} >>> … !
!
“Pet” link followed…
!Content-type: application/hal+json … !{ "type": "cat", "quantity": 0, "_links": { "add": { "href": "/basket/53c2a9f5fcb82e54c5d7a3a3/pets/cat", "method": "POST" } } }
!
!
!
>>> … >>> pet.links {u'add': HALNavigator(europythontalk.basket.53c2a9f5fcb82e54c5d7a3a3.pets.cat)} >>> >>> pet = pet.links['add'].create({}) >>> >>> pet.fetch() {u'type': u'cat', u'quantity': 1} >>> >>> pet.links {u'remove': HALNavigator(ep2014talk.basket.53c2a9f5fcb82e54c5d7a3a3.pets.cat)} >>> …
Follow the “add” link
!Content-type: application/hal+json … !{ "type": "cat", "quantity": 1, "_links": { "remove": { "href": "/basket/53c2a9f5fcb82e54c5d7a3a3/pets/cat", "method": "DELETE" } } }
“Add” link followed…
How do you define your resources?
from dougrain import Builder !!class BasketResource(object): … def get_builder(self): builder = Builder(self.uri) builder.set_property('id', self.id) pets = self._basket.pets() for pet in pets.values(): builder.add_link( 'pet', self.uri + ‘/pets/‘ + pet['type'], method=‘GET' ) return builder
For HAL you can use the python module dougrain
How do you define your routes?
def create_resource_response(api, response_code=200): return Response( simplejson.dumps(api.as_object()), response_code, content_type='application/hal+json' ) … @pet_shop.route('/basket/<id>', methods=['GET']) def basket(id): try: basket = APP_CONTROLLER.get_basket_resource(id) return create_resource_response(basket) except KeyError: api = Builder(request.url) return create_resource_response(api, 404) !!
You can use flask to define
the routes
Recap
Recap
Hypermedia controls
!
Guides users towards a goal
!
State of the entire app
changes
What is Hypermedia !
Loose coupling !
Simple approach !
Helps modelling business
interactions
Advantages !
Embedded Resources
!
API Forms !
Design Principles !
Profiles
Advanced topics !
flask !
dougrain !
restnavigator !
HAL+Json
Example !
Testing !
Design
Challenges !
Thank you!
Adriana Vasiu [email protected]
http://uk.linkedin.com/in/adrianavasiu
“Building Hypermedia APIs with HTML5 and
Node” (Mike Amundsen) !
“REST in Practice” (Jim Webber, Savas Parastatidis, Ian Robinson)
!
“RESTful Web APIs” (Leonard Richardson, Mike Amundsen, Sam Ruby)
Books !
Roy Fielding’s dissertation !
!
Steve Klabnik’s blog !
!
HAL Documentation
Web resources