Some pragmatism in client server API design


Published on

A collection of small ideas grasped over the years, in building client server APIs, that may help to avoid some pitfalls.

Published in: Engineering, Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Some pragmatism in client server API design

  1. 1. Pragmatism in client server API
  2. 2. • What will be said has been implemented a few times • There will be a second talk for the client side mainly for iOS • A few people to name whose interaction lead me get to all this: Ludovic Dujardin, Steeve Morin, Mathieu Ghaleb, Julien Duponchelle, Pierre-Yves Ritschard, Andi Geier, Quentin Adam Foreword
  3. 3. • Application/ Programming/ Interface • Certainly not a new idea (POSIX…) • Exposes a nice learnable and usable model with a set of methods and functions, of your maybe not so nice internals computer bowels • Learning by example : read as much API of different types API
  4. 4. Not really API per se but good to grasp examples. A small book recommendation
  5. 5. • The marketing guys probably heard that making an API can increase the business. Now be honest : you’re not the only one on the market • You will be adopted either because people need you either because your API is easy to grasp and use • This is Application : not KPI, not SPI, but API. So this is to do something. Coherency above everything
  6. 6. Example of deleting a relationship ! curl -XDELETE ' members/ID_OF_RELATIONSHIP_OF_THE_PERSON_IN_THEGROUP ! curl -XDELETE ' members/ID_OF_THE_PERSON_IN_THEGROUP Interface/implementation Nobody wants to see the intern of the body of a Vogue model NOT OK OK
  7. 7. void a_function(void *target, int param1, bool withOption1, bool withOption2, bool withOption3, bool withOption4); ! void a_function(void *target, int param1, uint32_t options_bits) ! ! enum { kFunctionOptionNone = 0x0000, kFunctionOption1 = 0x0001 kFunctionOption2 = 0x0002 kFunctionOption3 = 0x0004 }; Keep it to a minimum Endless parameters in C functions
  8. 8. • Web : Rails, Django, Symfony • They usually do more than APIs and it is easy to not separate the different pars • Look at Sinatra (Ruby), Flask/Django Rest Framework(Python), About modern and useful web frameworks
  9. 9. • From the start consider you deal with 3 clients • iOS, Android, Javascript (Angular, Backbone Ember JS) • If you implement a call “for a client” you’re taking the wrong path Multiple client
  10. 10. Client server case
  11. 11. • To do HTTP, learn HTTP, RFC 2616 • minimum GET, POST, PUT, DELETE, HEAD. What do they _mean_? • Then TRACE, OPTIONS, CONNECT, PATCH (recent RFC5789) • POST semantic has evolved towards a “do something” more than “Create by appending” Focus on HTTP from now
  12. 12. • There are enough error code not to invent new one really • Short test: 200 ? 206 ? 400? 401? 403? 409? 500? 503? • You can add somewhere in the returned data a descriptive message in addition to provide context • Caution : it may happen that some hackers may exploit also your error codes. So maybe have a version for debug versus prod Error have a meaning
  13. 13. • Certainly a buzz word component here. Who would pretend not to be REST? • For me : put the object to be addressed in the path and the parameters in the query string. ! ! • I do not pretend this is the ultimate truth Relax and REST parameter1=value1&parameter2=value2
  14. 14. • Weight each call, 3 times. • Or force some choices : e.g AWS EC2 all POST (I guess because those are commands) • Never do an API call because a client needs it. but because the product needs it Design phase
  15. 15. • This may remove some “path length” (e.g those are “my groups”) • Make sure it is possible to query data independently of their user metadata • Multiple login methods are possible (user/ password, Facebook, Google+…) There is often an user
  16. 16. • 2 families roughly, somewhere you are free to answer what you want • XML old and sometimes heavy to parse. If you do not need it ignore it. Do not believe XML is so simple (but knowing it is a great asset) • JSON more in the wave of today . Defines elementary structure (Array, Dictionary). Integrated with Javascript (Javascript Object Notation). Output Format
  17. 17. Usual Answer type An Object Multiple Objects
  18. 18. Usual Answer type:slices Multiple Objects from an bigger list
  19. 19. More On Slice • 2 philosophy for slices - Page : web oriented - offset/limit : all freedom • Can be completed with order/ascending • Client developers hate them • The key to smooth loading and scrolling
  20. 20. Debug set up
  21. 21. • Custom header fields “X-SERVERTIME” • Or format the data to report information Use all parts of a request
  22. 22. Always the same data path client server Always check the basics : pipelining (parallelism), zip compression
  23. 23. From the start report • Cheap and efficient. No need to do make complex system • Make every in house developer aware of the API • A reasonable goal is < 600ms back and forth, certainly < 200 ms in the server • Give a level to the user entity to activate remotely some debug feature and thus directly debug a user
  24. 24. From the start report
  25. 25. Environment • Prod and dev API • Create custom data set • Use the proper tools: Charles
  26. 26. Real life testing • Only real life will make your app solid • For a mobile app: go in the subway, in the street, in a car, • Thinks about network disappearing, user interruption (phone call), background tasking, airplane mode and how the API should help you recover in all cases
  27. 27. Object manipulation
  28. 28. • In general an API send back something that can be designated as object and is a dictionary • At the core it has two characteristics : a class and a uuid The basis
  29. 29. The choice of UUID • Database ID: not unique! • Complex FQDN like notation. Do not put too much meaning in it, somewhere someone will over complexity it • Intermediary step. !
  30. 30. The choice of UUID(2) • Can also generate uuid with uuid_gen (imagine you need to change DB technology), ! • This last solution avoid also to exposes (wrongly) interpretable numbers (they have only 67 users….) • Even if the object is not persistent is better to send a uuid and not let the client construct it
  31. 31. Be self describing
  32. 32. Impact on the client answer • No need to declare what will be in the answer. The object contains it. • The class is in the object. A generic parser can be written • A well behaved client would simply ignore unknown object or unknown attributes • The schema should always be : endpoint gives back objects
  33. 33. Object dependancies • What to put in ? Only uuid or all object (I prefer the later, cf Elastic search _source) • Avoid infinite loops
  34. 34. Object dependancies(2)
  35. 35. Object dependancies(3) • Now really and independently of dependancies : make a “person” class • As this is a growing list make a endpoint • Embedded dependancies when there is a boundary to the relationship
  36. 36. Client coherency • Should I change before or after the query, if it fails. Instant feedback versus real state • Send back the updated data as JSON , although you may need to work on what to send (e.g DELETE) but clearly in case of PUT • Leave on the client to decide when to change but make sure the API reflects always the server state
  37. 37. Fields API • Facebook is well known for this (Graph API, Send back only some attributes of an object • Fields are also a pain of client programming and require more server work • But this can make a big difference (especially at startup)
  38. 38. Why Fields API • Inside an implementation there can be joins • So on demand fetching is not only “I need this”, it is more “this field cost me X”. • Some client magic needed to find “what is missing”
  39. 39. Syntax • Simple level Note:making uuid always returned may not be a bad idea • Multi levels (class person and weapon) • Possible to define some aliases:e.g “all” in debug
  40. 40. Object versioning • When to update or not, likely after fetch (but one could thing of optimisation through use of fields).
  41. 41. Object versioning (2) • In current and normal use : one can avoid to update the UI if not needed (yes graphics can be expensive) • At startup by simply fetching version one can know if an object needs to be updated or if all is here. • A client backend storage will often go through following evolutions: refetch everything/ memory storage/disk storage/full offline mode
  42. 42. Living environment
  43. 43. Anticipating client change • Min iOS/Android client, max IOSAndroid Client etc… Easier on Javascript served
  44. 44. Server also can change A client can also send a version that it wants. Everything to maintain a certain level of forward/ backward compatibility
  45. 45. A few words on security (but really a few) • Don’t under-estimate that sometimes “Security by obscurity” is not completely stupid, but also do not do stupid things • Paranoid is not always the best. Can be costly in implementation time (cf OAuth) • Learn the basics : encryption (SHA1, MD5), concepts (authentification, authorization), clear versus not clear transmission, HTTPS
  46. 46. • Think not too late about anonymous mode . Can have an an impact on design • Real Basis : In auth mode identify every query with a token/sessionID A few words on security (but really a few)(2)
  47. 47. Thank You!