Andy Bennett, Founder, Knodium
This talk looks at how to make an HTTP API available as a self-contained procedure or function, just like any other library or API code that you might be used to using or importing into your programs.
Whether you're implementing an SDK for your own API or just trying to bind to an adhoc API that you want to use, this talk will cover how to do it in an elegant and simple way without lots of adhoc code duplication, needless boilerplate or irrelevant detail.
2. HTTP APIs As First Class Procedures
a@kno.dm
@databasescaling
Thursday, 25th September 2014
2014/09/24 APIconUK 2014 2 / 149
3. HTTP APIs As First Class Procedures
Cutting out SDK Complexity
a@kno.dm
@databasescaling
Thursday, 25th September 2014
2014/09/24 APIconUK 2014 3 / 149
5. GSM AT Command Set
cmd AT+CREG "Network Registration (ver.2)"
set AT+CREG=[<creg_stat>],<creg_urc>,<ci>
read AT+CREG?
+CREG:<creg_urc>,<creg_stat>[,<lac>,<ci>]
test AT+CREG=?
+CREG
2014/09/24 APIconUK 2014 5 / 149
6. GSM AT Command Set
cmd AT+CREG "Network Registration (ver.2)"
set AT+CREG=[<creg_stat>],<creg_urc>,<ci>
read AT+CREG?
+CREG:<creg_urc>,<creg_stat>[,<lac>,<ci>]
test AT+CREG=?
+CREG
2014/09/24 APIconUK 2014 6 / 149
7. GSM AT Command Set
cmd AT+CREG "Network Registration (ver.2)"
set AT+CREG=[<creg_stat>],<creg_urc>,<ci>
read AT+CREG?
+CREG:<creg_urc>,<creg_stat>[,<lac>,<ci>]
test AT+CREG=?
+CREG
2014/09/24 APIconUK 2014 7 / 149
8. GSM AT Command Set
cmd AT+CREG "Network Registration (ver.2)"
set AT+CREG=[<creg_stat>],<creg_urc>,<ci>
read AT+CREG?
+CREG:<creg_urc>,<creg_stat>[,<lac>,<ci>]
test AT+CREG=?
+CREG
2014/09/24 APIconUK 2014 8 / 149
9. GSM AT Command Set
cmd AT+CREG "Network Registration (ver.2)"
set AT+CREG=[<creg_stat>],<creg_urc>,<ci>
read AT+CREG?
+CREG:<creg_urc>,<creg_stat>[,<lac>,<ci>]
test AT+CREG=?
+CREG
2014/09/24 APIconUK 2014 9 / 149
10. GSM AT Command Set
cmd AT+CREG "Network Registration (ver.2)"
set AT+CREG=[<creg_stat>],<creg_urc>,<ci>
read AT+CREG?
+CREG:<creg_urc>,<creg_stat>[,<lac>,<ci>]
test AT+CREG=?
+CREG
int AT_CREG_test(int port, struct AT_result* result) {
int r = 0;
if ((r = sendcmd(port, "AT+CREG=?", result))) return r;
return recvresp(port, result);
}
2014/09/24 APIconUK 2014 10 / 149
11. Execution Tracing
DBrow *CursorNext(DB *env, DBcursor* cursor, DBresult* result) {
/* Increment the cursor to the next row in the direction
* that the cursor is travelling and return the row to
* the caller.
*/
...
}
2014/09/24 APIconUK 2014 11 / 149
44. REST
"Finally, I describe the lessons
learned from applying REST to the
design of the Hypertext Transfer
Protocol and Uniform Resource
Identifier standards, and from their
subsequent deployment in Web
client and server software."
-- Roy Fielding
2014/09/24 APIconUK 2014 44 / 149
45. REST
GET
Retrieves a representation of the requested
resource (current state)
POST
Create a new instance of a resource
PUT
Update an existing instance of a resource
DELETE
Remove an existing instance of a resource
2014/09/24 APIconUK 2014 45 / 149
47. DCE
"The Distributed Computing
Environment (DCE) is a software
system developed in the early 1990s"
2014/09/24 APIconUK 2014 47 / 149
48. DCE/RPC
"This system allows programmers to
write distributed software as if it were
all working on the same computer,
without having to worry about the
underlying network code."
2014/09/24 APIconUK 2014 48 / 149
49. DCE/RPC
"This system allows programmers to
write distributed software as if it were
all working on the same computer,
without having to worry about the
underlying network code."
2014/09/24 APIconUK 2014 49 / 149
50. Adhoc Binding
“I'm looking for a pretty generic,
fully featured REST client/API in
python. Not bare bones, but plush,
nice to use.”
http://stackoverflow.com/questions/4355997/is-there-a-generic-python-library-to-consume-rest-based-services
2014/09/24 APIconUK 2014 50 / 149
51. Adhoc Binding
“...an HTTP resource kit for Python. It
allows you to easily access to HTTP
resource and build objects around it.”
2014/09/24 APIconUK 2014 51 / 149
52. Adhoc Binding
“...an HTTP resource kit for Python. It
allows you to easily access to HTTP
resource and build objects around it.”
“[It] is a full HTTP client using pure
socket calls and its own HTTP parser.”
2014/09/24 APIconUK 2014 52 / 149
53. Adhoc Binding
api = API('http://myrestful/api/v1')
# GET /resource
api.resource.get()
# GET /resource (with accept header = application/json)
api.resource.get(format='json')
# GET /resource?attr=value
api.resource.get(attr=value)
# POST /resource
api.resource.post(attr=value, attr2=value2, ...)
# GET /resource/id/resource_collection
api.resoure(id).resource_collection().get()
2014/09/24 APIconUK 2014 53 / 149
54. Adhoc Binding
☺
api = API('http://myrestful/api/v1')
# GET /resource
api.resource.get()
# GET /resource (with accept header = application/json)
api.resource.get(format='json')
# GET /resource?attr=value
api.resource.get(attr=value)
# POST /resource
api.resource.post(attr=value, attr2=value2, ...)
# GET /resource/id/resource_collection
api.resoure(id).resource_collection().get()
2014/09/24 APIconUK 2014 54 / 149
55. Adhoc Binding
☺
api = API('http://myrestful/api/v1')
# GET /resource
api.resource.get()
# GET /resource (with accept header = application/json)
api.resource.get(format='json')
# GET /resource?attr=value
api.resource.get(attr=value)
# POST /resource
api.resource.post(attr=value, attr2=value2, ...)
# GET /resource/id/resource_collection
api.resoure(id).resource_collection().get()
2014/09/24 APIconUK 2014 55 / 149
56. Adhoc Binding
☺
api = API('http://myrestful/api/v1')
# GET /resource
api.resource.get()
☹
# GET /resource (with accept header = application/json)
api.resource.get(format='json')
# GET /resource?attr=value
api.resource.get(attr=value)
# POST /resource
☹
api.resource.post(attr=value, attr2=value2, ...)
# GET /resource/id/resource_collection
api.resoure(id).resource_collection().get()
2014/09/24 APIconUK 2014 56 / 149
57. Adhoc Binding
☺
api = API('http://myrestful/api/v1')
# GET /resource
api.resource.get()
# GET /resource (with accept header = application/json)
api.resource.get(format='json')
# GET /resource?attr=value
api.resource.get(attr=value)
# POST /resource
api.resource.post(attr=value, attr2=value2, ...)
# GET /resource/id/resource_collection
api.resoure(id).resource_collection().get()
2014/09/24 APIconUK 2014 57 / 149
58. Adhoc Binding
☺
api = API('http://myrestful/api/v1')
# GET /resource
api.resource.get()
# GET /resource (with accept header = application/json)
api.resource.get(format='json')
# GET /resource?attr=value
api.resource.get(attr=value)
# POST /resource
api.resource.post(attr=value, attr2=value2, ...)
# GET /resource/id/resource_collection
api.resoure(id).resource_collection().get()
☹
2014/09/24 APIconUK 2014 58 / 149
118. ● HTTP Implementation
● HTTP Client
● URI / URL Library
● Media Format Libraries
● A Way To Put It All Together
2014/09/24 APIconUK 2014 118 / 149
119. ● HTTP Implementation
● HTTP Client
● URI / URL Library
● Media Format Libraries
● A Way To Put It All Together
2014/09/24 APIconUK 2014 119 / 149
120. ● HTTP Implementation
● HTTP Client
● URI / URL Library
● Media Format Libraries
● A Way To Put It All Together
66 lines
2014/09/24 APIconUK 2014 120 / 149
121. Putting It All Together
(module dropbox-lolevel
(dropbox
make-dropbox-app
account/info
files:get
files:put
files:post
metadata
delta
revisions
restore
search
shares
media
copy-ref
thumbnails
chunked_upload
commit_chunked_upload
fileops/copy
fileops/create_folder
fileops/delete
fileops/move
callback
old-output-port)
2014/09/24 APIconUK 2014 121 / 149