Slide 1

Slide 1 text

API Design Matters Anthony Eden Monday, September 26, 11

Slide 2

Slide 2 text

Why? Monday, September 26, 11 How many of you are write software for a living? How many of you design APIs for a living? If you write software, you design APIs.

Slide 3

Slide 3 text

APIs are the product Monday, September 26, 11 Used both internally and externally.

Slide 4

Slide 4 text

APIs outlive implementations Monday, September 26, 11 Clients expect APIs to be stable even as implementations change.

Slide 5

Slide 5 text

APIs lead everything else Monday, September 26, 11 API helps guide the implementation, both the implementation of the API as well as the implementation of client code.

Slide 6

Slide 6 text

Principles Monday, September 26, 11

Slide 7

Slide 7 text

Easy to learn Monday, September 26, 11 Principle of least astonishment. Think about naming. Lead by example.

Slide 8

Slide 8 text

Produces readable code Monday, September 26, 11 From the client perspective, code that uses an API must be readable. A good API will encourage good client code.

Slide 9

Slide 9 text

Easy to extend Monday, September 26, 11 APIs grow with new requirements and should be designed with this in mind. APIs should also be easy to split into smaller APIs.

Slide 10

Slide 10 text

Hard to misuse Monday, September 26, 11 Makes it easier to write correct code. Avoids relying on order or side effects.

Slide 11

Slide 11 text

Sufficiently powerful Monday, September 26, 11 As small as possible but never smaller. Only implements the functionality required to get the job done. Adding is easy, removing is much more difficult because dependencies are broken.

Slide 12

Slide 12 text

Principles v2* * because everyone loves the letter ‘C’ Monday, September 26, 11

Slide 13

Slide 13 text

Consistent Monday, September 26, 11 Consistent with existing APIs Consistent naming throughout “Economy of concepts” - introduce new concepts with frugality

Slide 14

Slide 14 text

Clear Monday, September 26, 11 Clarity of code. Clarity of intent.

Slide 15

Slide 15 text

Convenient Monday, September 26, 11 Easier to use the API than to implement an alternative API. Eschews complexity for usability.

Slide 16

Slide 16 text

Concise Monday, September 26, 11 Brief but comprehensive.

Slide 17

Slide 17 text

Complete Monday, September 26, 11 Does the job, no more, no less

Slide 18

Slide 18 text

Examples Monday, September 26, 11

Slide 19

Slide 19 text

Net::HTTP Monday, September 26, 11 Consistent, clear, convenient, concise, complete?

Slide 20

Slide 20 text

Net::HTTP.get_print 'example.com', '/' Net::HTTP.get_print URI.parse('http://example.com/') Net::HTTP.get ‘example.com’, ‘/’ Net::HTTP.get URI.parse(‘http://example.com/’) Monday, September 26, 11 The difference between get_print is one returns a string and one prints to stdout.

Slide 21

Slide 21 text

res = Net::HTTP.start ‘example.com’ do |http| http.get ‘/’ end get(path, initheader = {}, dest = nil) Monday, September 26, 11 initheader is a Hash of request headers “dest argument is obsolete. It still works but you must not use it.” Oh, and by the way...

Slide 22

Slide 22 text

“If called with a block, yields each fragment of the entity body in turn as a string as it is read from the socket. Note that in this case, the returned response object will not contain a (meaningful) body.” Monday, September 26, 11 Also...

Slide 23

Slide 23 text

In version 1.1, this method might raise an exception for 3xx (redirect). In this case you can get a HTTPResponse object by “anException.response“. Monday, September 26, 11 except...

Slide 24

Slide 24 text

In version 1.2, this method never raises exception. Monday, September 26, 11

Slide 25

Slide 25 text

Monday, September 26, 11 * get_print (side effects, unnecessary methods, does more than it should) * .start vs. #start (unnecessary methods) * post vs. post2 * D and Proxy (methods using class-naming style) * version_1_1 (side effects, hard to extend) * newobj (unecessary) * exceptions for flow control (raise exceptions for 3xx redirects) * SSL methods (does more than it should) * proxy methods (does more than it should)

Slide 26

Slide 26 text

Typheous Monday, September 26, 11 Consistent, clear, convenient, concise, complete?

Slide 27

Slide 27 text

request = Typhoeus::Request.new("http://example.com") hydra = Typhoeus::Hydra.new hydra.queue(request) hydra.run response = request.response response.body Monday, September 26, 11 or if you need shortcuts...

Slide 28

Slide 28 text

response = Typhoeus::Request.get("http://example.com") response.body Monday, September 26, 11

Slide 29

Slide 29 text

response = Typhoeus::Request.post("http://example.com", { :params => {:person => {:name => “John”}} }) response.body Monday, September 26, 11

Slide 30

Slide 30 text

Faraday Monday, September 26, 11 Consistent, clear, convenient, concise, complete?

Slide 31

Slide 31 text

response = Faraday.get("http://example.com") response.body Monday, September 26, 11

Slide 32

Slide 32 text

conn = Faraday.new(:url => 'http://sushi.com') do |builder| builder.use Faraday::Request::JSON builder.use Faraday::Response::Logger end response = conn.get '/nigiri/sake.json', ‘X-Example’ => ‘foo’ response.body Monday, September 26, 11

Slide 33

Slide 33 text

openuri Monday, September 26, 11 The best API is no API open(url) becomes like opening a file

Slide 34

Slide 34 text

require ‘open-uri’ open("http://example.com/") do |f| f.each_line { |line| p line } end Monday, September 26, 11

Slide 35

Slide 35 text

Monday, September 26, 11 Consistent, clear, convenient, concise, complete.

Slide 36

Slide 36 text

Techniques Monday, September 26, 11

Slide 37

Slide 37 text

Ask & Think Monday, September 26, 11 Talk to those that need it Know what is required Be the client

Slide 38

Slide 38 text

Client first Monday, September 26, 11 Clear and concise requirements Readme driven design Sample client code Tests

Slide 39

Slide 39 text

Implementation second Monday, September 26, 11 Favor a clear and concise API with a difficult implementation over allowing the implementation to bleed into the API. This is why we love Ruby!

Slide 40

Slide 40 text

Address your audience Monday, September 26, 11 Define APIs at the appropriate level for the type of consumer Domain experts will expect appropriate jargon Non-domain experts will want to avoid being baffled

Slide 41

Slide 41 text

Choose good defaults Monday, September 26, 11 But make sure to document them

Slide 42

Slide 42 text

Separate API and SPI Monday, September 26, 11 API is the public consumer interface SPI is the public provider interface (and is used for extension)

Slide 43

Slide 43 text

Consistent, clear, convenient, concise, complete? Monday, September 26, 11 Ask yourself

Slide 44

Slide 44 text

The best API is no API Monday, September 26, 11 Jasmine Blanchette, The Little Manual of API Design

Slide 45

Slide 45 text

Things to think about Monday, September 26, 11 If you are a software developer, then you are an API designer. Design with purpose and intent.

Slide 46

Slide 46 text

What are other examples of good APIs to learn from? Monday, September 26, 11

Slide 47

Slide 47 text

What can we learn from APIs in functional languages? Monday, September 26, 11

Slide 48

Slide 48 text

How do you refactor APIs to make them better? Monday, September 26, 11 Keep in mind the challenges of existing API users.

Slide 49

Slide 49 text

http://www.flickr.com/photos/heartart/79018288/ http://www.flickr.com/photos/larou/3505324393/ http://www.flickr.com/photos/nuagedenuit/155699074/ http://www.flickr.com/photos/fishbulb1022/4268407490/ http://www.flickr.com/photos/larachris/182959784/ http://www.flickr.com/photos/bartzoni/4201610982/ http://www.flickr.com/photos/stuckincustoms/3932778019/ http://www.flickr.com/photos/stathis1980/4285295041/ Monday, September 26, 11

Slide 50

Slide 50 text

How to Design a Good API and Why it Matters Joshua Bloch The Little Manual of API Design Jasmin Blanchette Monday, September 26, 11