Slide 1

Slide 1 text

! From GitHub’s API support, ...with <3 @izuzak github.com/izuzak

Slide 2

Slide 2 text

! GitHub The Product

Slide 3

Slide 3 text

Build software better, together

Slide 4

Slide 4 text

! GitHub The Company

Slide 5

Slide 5 text

! Build a Great Company

Slide 6

Slide 6 text

! Optimize For Happiness

Slide 7

Slide 7 text

! Distributed - 214 hubbers, 102 cities

Slide 8

Slide 8 text

! " Recorded # Internal Tools $ Asynchronous

Slide 9

Slide 9 text

! Support

Slide 10

Slide 10 text

! 16 supportocats 4.5 million users ! ! Daily stats: ! 300 new tickets 550 responses Goal: Create superfans

Slide 11

Slide 11 text

! Classy, Human, Smart, Low ego, Interesting

Slide 12

Slide 12 text

! Logic, Empathy, Transparency, Honesty, Surprise, Delight

Slide 13

Slide 13 text

Continuous Deployment

Slide 14

Slide 14 text

Global Userbase

Slide 15

Slide 15 text

! Life of a feature ! Support-driven development

Slide 16

Slide 16 text

! Ideas and Development Feedback

Slide 17

Slide 17 text

! Ideas and Development Internal Launch Documentation, Support ramp-up

Slide 18

Slide 18 text

! Ideas and Development Internal Launch Public Launch UX feedback, Bug reports

Slide 19

Slide 19 text

! Ideas and Development Internal Launch Public Launch Iteration Feature requests, Bug reports, How-to questions

Slide 20

Slide 20 text

Halp

Slide 21

Slide 21 text

Halp

Slide 22

Slide 22 text

Halp Issues

Slide 23

Slide 23 text

Halp Issues Campfire

Slide 24

Slide 24 text

Halp Issues Campfire

Slide 25

Slide 25 text

Halp Issues Campfire

Slide 26

Slide 26 text

! API Support

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

$ curl https://api.github.com/users/ihabunek ! { "login": "ihabunek", "id": 482138, "gravatar_id": "890c6bbeb909f220b1fc47948e86cee0", "type": "User", "name": "Ivan Habunek", "location": "Zagreb, Croatia", "email": "[email protected]", "public_repos": 34, "followers": 11, "following": 6, "created_at": "2010-11-15T11:53:51Z", "updated_at": "2013-10-18T21:59:08Z", "public_gists": 12, "url": "https://api.github.com/users/ihabunek", "html_url": "https://github.com/ihabunek", "followers_url": "https://api.github.com/users/ihabunek/followers", "subscriptions_url": "https://api.github.com/users/ihabunek/subscriptions", "organizations_url": "https://api.github.com/users/ihabunek/orgs", "repos_url": "https://api.github.com/users/ihabunek/repos" }

Slide 29

Slide 29 text

$ curl https://api.github.com/users/ihabunek ! { "login": "ihabunek", "id": 482138, "gravatar_id": "890c6bbeb909f220b1fc47948e86cee0", "type": "User", "name": "Ivan Habunek", "location": "Zagreb, Croatia", "email": "[email protected]", "public_repos": 34, "followers": 11, "following": 6, "created_at": "2010-11-15T11:53:51Z", "updated_at": "2013-10-18T21:59:08Z", "public_gists": 12, "url": "https://api.github.com/users/ihabunek", "html_url": "https://github.com/ihabunek", "followers_url": "https://api.github.com/users/ihabunek/followers", "subscriptions_url": "https://api.github.com/users/ihabunek/subscriptions", "organizations_url": "https://api.github.com/users/ihabunek/orgs", "repos_url": "https://api.github.com/users/ihabunek/repos" }

Slide 30

Slide 30 text

$ curl https://api.github.com/users/ihabunek ! { "login": "ihabunek", "id": 482138, "gravatar_id": "890c6bbeb909f220b1fc47948e86cee0", "type": "User", "name": "Ivan Habunek", "location": "Zagreb, Croatia", "email": "[email protected]", "public_repos": 34, "followers": 11, "following": 6, "created_at": "2010-11-15T11:53:51Z", "updated_at": "2013-10-18T21:59:08Z", "public_gists": 12, "url": "https://api.github.com/users/ihabunek", "html_url": "https://github.com/ihabunek", "followers_url": "https://api.github.com/users/ihabunek/followers", "subscriptions_url": "https://api.github.com/users/ihabunek/subscriptions", "organizations_url": "https://api.github.com/users/ihabunek/orgs", "repos_url": "https://api.github.com/users/ihabunek/repos" }

Slide 31

Slide 31 text

! Superfans, Developers, Researchers, Businesses

Slide 32

Slide 32 text

! Millions of API calls / hour

Slide 33

Slide 33 text

! API design ! This talk is not about that, but it’s important for support!

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

tl;dr

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

! “My API call is not working!” ! “curl -v or it didn’t happen.”

Slide 38

Slide 38 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! * About to connect() to api.github.com port 443 (#0) * Trying 192.30.252.139... * Connected to api.github.com (192.30.252.139) port 443 (#0) * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS handshake, Server finished (14): * SSLv3, TLS handshake, Client key exchange (16): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSL connection using RC4-SHA * Server certificate: * subject: C=US; ST=California; L=San Francisco; O=GitHub, Inc.; CN=*.github.com * start date: 2012-04-30 00:00:00 GMT * expire date: 2014-07-09 12:00:00 GMT * subjectAltName: api.github.com matched * issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert High Assurance CA-3 * SSL certificate verify ok. ! > DELETE /repos/izuzak/test HTTP/1.1 ...

Slide 39

Slide 39 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! * Could not resolve host: api.github.com; nodename nor servname provided, or not known * Closing connection #0 ! * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS handshake, Server finished (14): * SSLv3, TLS handshake, Client key exchange (16): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSL connection using RC4-SHA * Server certificate: * subject: C=US; ST=California; L=San Francisco; O=GitHub, Inc.; CN=*.github.com * start date: 2012-04-30 00:00:00 GMT * expire date: 2014-07-09 12:00:00 GMT * subjectAltName: api.github.com matched * issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert High Assurance CA-3 * SSL certificate verify ok. ! > DELETE /repos/izuzak/test HTTP/1.1 ...

Slide 40

Slide 40 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! * About to connect() to api.github.com port 443 (#0) * Trying 192.30.252.139... * Connected to api.github.com (192.30.252.139) port 443 (#0) ! * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS alert, Server hello (2): * SSL certificate problem: unable to get local issuer certificate * Closing connection 0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: http://curl.haxx.se/docs/sslcerts.html ! ! ! ! ! ! ! ! ! ! > DELETE /repos/izuzak/test HTTP/1.1

Slide 41

Slide 41 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! * About to connect() to api.github.com port 443 (#0) * Trying 192.30.252.139... * Connected to api.github.com (192.30.252.139) port 443 (#0) ! * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS handshake, Server finished (14): * SSLv3, TLS handshake, Client key exchange (16): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSL connection using RC4-SHA * Server certificate: * subject: C=US; ST=California; L=San Francisco; O=GitHub, Inc.; CN=*.github.com * start date: 2012-04-30 00:00:00 GMT * expire date: 2014-07-09 12:00:00 GMT * subjectAltName: api.github.com matched * issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert High Assurance CA-3 * SSL certificate verify ok. ! > DELETE /repos/izuzak/test HTTP/1.1

Slide 42

Slide 42 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! > DELETE /repos/izuzak/test HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5 > Host: api.github.com > Accept: */* ! < HTTP/1.1 404 Not Found < Date: Mon, 21 Oct 2013 15:23:50 GMT < Content-Type: application/json; charset=utf-8 < Content-Length: 86 < Access-Control-Allow-Credentials: true < Access-Control-Expose-Headers: ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, ... < Access-Control-Allow-Origin: * < X-RateLimit-Limit: 5000 < X-RateLimit-Remaining: 4999 < X-RateLimit-Reset: 1382372630 < X-OAuth-Scopes: user, public_repo, repo, gist < X-Accepted-OAuth-Scopes: delete_repo < X-GitHub-Media-Type: github.beta < X-Content-Type-Options: nosniff < X-GitHub-Request-Id: 4D3B8BF5:78F1:1E760DDF:52654706 ! { ... }

Slide 43

Slide 43 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! > DELETE /repos/izuzak/test HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5 > Host: api.github.com > Accept: */* ! < HTTP/1.1 404 Not Found < Date: Mon, 21 Oct 2013 15:23:50 GMT < Content-Type: application/json; charset=utf-8 < Content-Length: 86 < Access-Control-Allow-Credentials: true < Access-Control-Expose-Headers: ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, ... < Access-Control-Allow-Origin: * < X-RateLimit-Limit: 5000 < X-RateLimit-Remaining: 4999 < X-RateLimit-Reset: 1382372630 < X-OAuth-Scopes: user, public_repo, repo, gist < X-Accepted-OAuth-Scopes: delete_repo < X-GitHub-Media-Type: github.beta < X-Content-Type-Options: nosniff < X-GitHub-Request-Id: 4D3B8BF5:78F1:1E760DDF:52654706 ! { ... }

Slide 44

Slide 44 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! > DELETE /repos/izuzak/test HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5 > Host: api.github.com > Accept: */* ! < HTTP/1.1 404 Not Found < Date: Mon, 21 Oct 2013 15:23:50 GMT < Content-Type: application/json; charset=utf-8 < Content-Length: 86 < Access-Control-Allow-Credentials: true < Access-Control-Expose-Headers: ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, ... < Access-Control-Allow-Origin: * < X-RateLimit-Limit: 5000 < X-RateLimit-Remaining: 4999 < X-RateLimit-Reset: 1382372630 < X-OAuth-Scopes: user, public_repo, repo, gist < X-Accepted-OAuth-Scopes: delete_repo < X-GitHub-Media-Type: github.beta < X-Content-Type-Options: nosniff < X-GitHub-Request-Id: 4D3B8BF5:78F1:1E760DDF:52654706 ! { ... }

Slide 45

Slide 45 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! > DELETE /repos/izuzak/test HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5 > Host: api.github.com > Accept: */* ! < HTTP/1.1 404 Not Found < Date: Mon, 21 Oct 2013 15:23:50 GMT < Content-Type: application/json; charset=utf-8 < Content-Length: 86 < Access-Control-Allow-Credentials: true < Access-Control-Expose-Headers: ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, ... < Access-Control-Allow-Origin: * < X-RateLimit-Limit: 5000 < X-RateLimit-Remaining: 4999 < X-RateLimit-Reset: 1382372630 < X-OAuth-Scopes: user, public_repo, repo, gist < X-Accepted-OAuth-Scopes: delete_repo < X-GitHub-Media-Type: github.beta < X-Content-Type-Options: nosniff < X-GitHub-Request-Id: 4D3B8BF5:78F1:1E760DDF:52654706 ! { }

Slide 46

Slide 46 text

! “My API call is not working!” ! “Use the response (headers), Luke!”

Slide 47

Slide 47 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! > DELETE /repos/izuzak/test HTTP/1.1 ! < HTTP/1.1 404 Not Found ! < X-OAuth-Scopes: user, public_repo, repo, gist < X-Accepted-OAuth-Scopes: delete_repo ! { ... }

Slide 48

Slide 48 text

! $ curl -v -X DELETE 'Authorization: token XXX' https://api.github.com/repos/izuzak/test ! > DELETE /repos/izuzak/test HTTP/1.1 ! < HTTP/1.1 404 Not Found ! < X-OAuth-Scopes: user, public_repo, repo, gist < X-Accepted-OAuth-Scopes: delete_repo ! { }

Slide 49

Slide 49 text

! “My API call is not working!” ! “Use the response (body), Luke!”

Slide 50

Slide 50 text

! $ curl -v https://api.github.com/search/repositories?q=webcampzg ! > GET /search/repositories?q=webcampzg HTTP/1.1 > Accept: */* < HTTP/1.1 415 Unsupported Media Type ! ! ! ! ! !

Slide 51

Slide 51 text

! $ curl -v https://api.github.com/search/repositories?q=webcampzg ! > GET /search/repositories?q=webcampzg HTTP/1.1 > Accept: */* < HTTP/1.1 415 Unsupported Media Type < Content-Type: application/json; charset=utf-8 { "message": "If you would like to help us test the Search API during its preview period, you must specify a custom media type in the 'Accept' header. Please see the docs for full details.", "documentation_url": "http://developer.github.com/v3/search#preview-mode" }

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

! “Can you bump my API rate limit?” ! “Sure! Also, let see if we can find a way to optimize your API usage.”

Slide 54

Slide 54 text

! “What if the API changes and my app stops working?” ! “When will you add feature X?” ! “We blog/tweet about upcoming changes. Breaking changes are avoided and made in new API versions.”

Slide 55

Slide 55 text

! API Support outside [email protected]

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

! “GitHub can’t seem to do X ?” ! “Have you seen our API?”

Slide 60

Slide 60 text

! Easter eggs

Slide 61

Slide 61 text

! $ curl https://api.github.com/octocat?s=Thank%20you,%20Web%20Camp%20Zagreb!%20%3C3 ! ! MMM. .MMM MMMMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMMMM ________________________________ MMMMMMMMMMMMMMMMMMMMM | | MMMMMMMMMMMMMMMMMMMMMMM | Thank you, Web Camp Zagreb! <3 | MMMMMMMMMMMMMMMMMMMMMMMM |_ ____________________________| MMMM::- -:::::::- -::MMMM |/ MM~:~ ~:::::~ ~:~MM .. MMMMM::. .:::+:::. .::MMMMM .. .MM::::: ._. :::::MM. MMMM;:::::;MMMM -MM MMMMMMM ^ M+ MMMMMMMMM MMMMMMM MM MM MM MM MM MM MM MM MM MM MM .~~MM~MM~MM~MM~~. ~~~~MM:~MM~~~MM~:MM~~~~ ~~~~~~==~==~~~==~==~~~~~~ ~~~~~~==~==~==~==~~~~~~ :~==~==~==~==~~

Slide 62

Slide 62 text

! The End