Top Banner
Developers are users too Why the user experience of your API sucks @craignicol #yourapisucks
28

Developers are users too #yourapisucks

Jan 22, 2018

Download

Software

Craig Nicol
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Developers are users too #yourapisucks

Developers are users tooWhy the user experience of your API sucks

@craignicol #yourapisucks

Page 2: Developers are users too #yourapisucks

Developing Android Apps With Xamarin in C#

http://bit.ly/xamarin-edin

2 Days : 10th – 11th November, Edinburgh

Discount code to get an additional £100 off early bird tickets : EB100

Page 3: Developers are users too #yourapisucks

One month to the deadline...

Page 4: Developers are users too #yourapisucks

Talk my language

Using your domain terms rather than

mine

Line1: 1A Queen Anne Drive,

Line2: Lochend Ind Estate

City: Edinburgh

Postcode: EH28 8PL

Postcode: EH28 8PL

Easting: 8212096

Northing: -6213914Postcode: EH28 8PL

Page 5: Developers are users too #yourapisucks

Weakest link

Using basic, or no authentication. You

should not be my weakest link

http://www.example.com/api/pay

?cardnumber=12341234123412

34&ccv=1234&expirymonth=12&

expiryyear=12&amount=123456

Page 6: Developers are users too #yourapisucks

Open kimono

Unsecured authentication

http://www.example.com/api

/pay?username=bob&passw

ord=supersecret

Page 7: Developers are users too #yourapisucks

Side effects

Not understanding idempotence. I can

just about forgive post everything, but

not get with side effects

http://www.example.com/api/createTransaction?...

Page 8: Developers are users too #yourapisucks

Data obesity

Don’t assume fat pipes, send as little

data as possible

Page 9: Developers are users too #yourapisucks

Busy waiting?

Don’t keep the caller waiting. If it’s

going to take a while, use callbacks or

another form of notification.

Page 10: Developers are users too #yourapisucks

Exceptional validation

Returning exceptions as validation.

Validate everything, and return

multiple errors.

And don’t return errors on an

alternative channel (such as email).

NOT:

HTTP 500 - Credit Card number invalid

BETTER:

HTTP 400

{

validationErrors: [

{“CreditCardNumber” : “Must be 16

characters”}

{“ExpiryDate” : “Must be in the future”}

{“CCV” : “Is required”}

]

}

Page 11: Developers are users too #yourapisucks

https://http.cat/404

Page 12: Developers are users too #yourapisucks

A forest of confusion

Multiple, inconsistent APIs, especially

inconsistent authentication

GET /cat

{ Name : “Garfield” }

GET /food/index.php/fooditem/1

🍌

Page 13: Developers are users too #yourapisucks

Inconsistent behaviour

Inconsistent behavior

GET /cat

{ Name : “Garfield” }

GET /cat

{ Name : “Jatt” }

GET /cat

{ Name : “Lion-o” }

GET /cat

🍌

Page 14: Developers are users too #yourapisucks

Breaking the contract

Adding versioning to an existing API,

poorly - breaking the contract. See

http://www.troyhunt.com/2014/02/yo

ur-api-versioning-is-wrong-which-

is.html

Today:

http://www.example.com/api/getAddress?postcode=

EH28%208PL

Tomorrow:

HTTP POST

http://www.example.com/api/getAddress

X-www-form-urlencoded

API-version: “v1.1”

Search-type: “postcode-lookup”

Input: “EH28 8PL”

Page 15: Developers are users too #yourapisucks

Late notice

Or even negative notice of changes -

“we switched this off 2 weeks ago”

⌛🚫

Page 16: Developers are users too #yourapisucks

Not Invented Here

Not Invented Here

https://xkcd.com/927/

Page 17: Developers are users too #yourapisucks

Verbosity compounds reducible complexity

E.g. Win32 API is often cryptic and

long-winded

Use sensible defaults

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){

WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);wcex.style = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc = WndProc;wcex.cbClsExtra = 0;wcex.cbWndExtra = 0;wcex.hInstance = hInstance;wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));wcex.hCursor = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName = NULL;wcex.lpszClassName = szWindowClass;wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

if (!RegisterClassEx(&wcex)){

MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Win32 Guided Tour"), NULL);return 1;

}

hInst = hInstance; // Store instance handle in our global variableHWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,500, 100, NULL, NULL, hInstance, NULL );

if (!hWnd){

MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL);

return 1;}

ShowWindow(hWnd,nCmdShow);UpdateWindow(hWnd);

MSG msg;while (GetMessage(&msg, NULL, 0, 0)){

TranslateMessage(&msg);DispatchMessage(&msg);

}return (int) msg.wParam;

}

HWND hWnd = CreateWindow(

szWindowClass,szTitle,

WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,500, 100,NULL,NULL,hInstance,NULL

);

https://msdn.microsoft.com/en-

us/library/bb384843.aspx

Page 18: Developers are users too #yourapisucks

Errors as a side effect

Return code is a constant, errors are a

side effect (HTTP 200, or return -1 in

C)

Success : ERROR -

Credit Card Expiry Date is in the past

Page 19: Developers are users too #yourapisucks

Illegal Character

Bad security - ask anyone with a Flat

a/b address or a Paddy O'Malley name

Page 20: Developers are users too #yourapisucks

Hidden Prerequisites

Hidden prerequisites - throwing an

error when submitting an order

because you didn't call

ExpectCreditCard first

Page 21: Developers are users too #yourapisucks

You said what?

Documentation out of sync with code.

Try swashbuckling

getPostcode(double opt)

This method takes returns

the current longitude and

latitude of the user based

on the information provided

by their device.

Page 22: Developers are users too #yourapisucks

Sucking Eggs

Teaching Granny to suck eggs

getAddressFromPostcode

(string postcode)

This method takes a

postcode and returns the

associated address.

Page 23: Developers are users too #yourapisucks

Be Explicit

Documentation should be explicit

Page 24: Developers are users too #yourapisucks

Use the platform

Legacy models VS JSON-native {

Name : “Your Woman”

Address : “<Line1>My House</Line1>

<Line2>My Street</Line2>

<Town>White Town</Town>

<Postcode>EE11EE</Postcode>”

}

Page 25: Developers are users too #yourapisucks

Strawman Testing

Test data / API out of sync with live

Testing the wrong thing

Planet Earth (for testing only)

Page 26: Developers are users too #yourapisucks

Tests doomed to succeed

Incomplete test data: imagine

postcode lookup where test addresses

are all SW...

No Flat x/y

No BFPO

No Irish or other EU addresses

Page 27: Developers are users too #yourapisucks

Takeaways : avoiding the axe

User first : Design from the outside in

If there’s a standard, use it

Be consistent

Be clear

Be helpful, but only when asked

Page 28: Developers are users too #yourapisucks

Over to youHave you seen an API that

sucked?

https://craignicol.wordpress.com

https://twitter.com/craignicol

https://plus.google.com/+CraigNicolGeek

Continue the discussion at theCodeCraftConf, 16th September at CitizenM : http://conf.codecraftuk.org/

10% Ticket Discount with code DevsUsersToo

I’ll be guiding a session on Writing Usable APIs