-
-
Save sjelfull/5618069 to your computer and use it in GitHub Desktop.
Revisions
-
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 19 additions and 14 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,22 +9,35 @@ 1. Use the query string for paired params instead of `/users/id/5/active/true`. _Your API does not need to be SEO optimised._ 1. `?format=xml` is stupid, use an `Accept: application/xml` header. I added this to the CodeIgniter Rest Server once for lazy people, and now people think it's a thing. It's not. ### Resources are EVERYTHING 1. You're always either asking for one resource, or multiple. If its one, just return that data as an array. If you've asked for multiple, then return them in a plural parent element (such as "users"). 2. Two resources in different locations should look identical (your iPhone dev will love you for this). This could be `/me/friends` and `/users/5/friends`, or embeded data. 3. If I want multiple resources in one call, then give them to me. `/users/X,Y,Z` in a `"users"` array works nicely. 4. If you ask for multiple and some results exist, shove that in a "users" array. 5. If you ask for multiple but find none, then a 404 makes sense. ### JSON, XML or shut up 1. Don't spend forever trying to make your system output everything under the sun. Sure you can output [lolcat](http://api.flickr.com/services/feeds/photos_public.gne?id=35034363287@N01&lang=en-us&format=lolcode), but you don't need to. 2. Tell your users to send you JSON or XML in the body. Messing around with `application/x-www-form-urlencoded` just for `$_POST['foo']` is no good, especially when any decent framework (like Laravel 4) will allow `Input::json('foo')` anyway. 3. No payload parameters. I've seen APIs accept `application/x-www-form-urlencoded` with a `json={}` parameter. If you think that is a good idea it's time you re-train as a yoga teacher or something, the stress is effecting your judgement. ### Authentication 1. OAuth 2 is the shit. A few people wrote ranty arguments about how it's insecure, because they weren't using SSL. 2. Use SSL. 3. Make sure your OAuth 2 implementation is spec compliant, or you're going to have a bad time. [This one is](https://github.com/php-loep/oauth2-server). ### Caching 1. Your API needs a shorter memory than my favorite fruit is watermelon. No state, no sessions, no IP recognition. Don't guess, let them tell you who they are with their access token. 2. Caching should only happen on popular endpoints where there is no user context, and you know its not going to change in the timeframe. 3. The `Cache-Control` header let's people know if they can (or should) cache stuff. If other devs ignore those headers then its their problem. ### Background all the things 1. "When the user sends us an image, resize it, upload it to S3, send an email then show a confirmation". Nope. That should be at least one background job, preferably 3, with an IMMEDIATE response. Ditch off to one "image_processing" job to get things going. 2. Create an "email" job, a "sms" job and a "APN" job for example, so you can generically send out all sorts of contact stuff from your API, your other jobs, etc without infecting your API with all that stuff. 3. Put your workers on a different server. Your API server is busy enough handling HTTP requests in responses, don't make it thing about anything else. @@ -35,14 +48,6 @@ 3. Dont make the client do math. 4. OUTPUT TOTALS. I'm looking at you Facebook. Why do I have to poll "next" 20 times to manually count() how many friends a specific user has when you obviously know the answer already? GAH! ### Response Codes 1. Give me an actual error message, not just a code. "Oh yay, a E40255 just happend" --Nobody. -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 14 additions and 14 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,22 +4,18 @@ 1. Most DB drivers [for PHP] will show integers as numeric strings and `false` as `"0"`, so you want to typecast them. 1. Unless you're using an ORM with "hidden" functionality, people will see passwords, salts and all sorts of fancy codes. If you add one and forget to put it in your `$hidden` array then OOPS! ### Use the URI sparingly, and correctly 1. Use the query string for paired params instead of `/users/id/5/active/true`. _Your API does not need to be SEO optimised._ 1. `?format=xml` is stupid, use an `Accept: application/xml` header. I added this to the CodeIgniter Rest Server once for lazy people, and now people think it's a thing. It's not. ### JSON, XML or shut up 1. Don't spend forever trying to make your system output everything under the sun. Sure you can output [lolcat](http://api.flickr.com/services/feeds/photos_public.gne?id=35034363287@N01&lang=en-us&format=lolcode), but you don't need to. 2. Tell your users to send you JSON or XML in the body. Messing around with `application/x-www-form-urlencoded` just for `$_POST['foo']` is no good, especially when any decent framework (like Laravel 4) will allow `Input::json('foo')` anyway. 3. No payload parameters. I've seen APIs accept `application/x-www-form-urlencoded` with a `json={}` parameter. If you think that is a good idea it's time you re-train as a yoga teacher or something, the stress is effecting your judgement. ### Your API needs a shorter memory than my favorite fruit is watermelon 1. No state. Your user is an unknown entity, let them tell you who they are with an access token. No guesswork, ignore the IP, let them tell you. 2. Caching should only happen on popular endpoints where there is no user context, and you know its not going to change in the timeframe. @@ -47,11 +43,6 @@ 4. If you ask for multiple and some results exist, shove that in a "users" array. 5. If you ask for multiple but find none, then a 404 makes sense. ### Response Codes 1. Give me an actual error message, not just a code. "Oh yay, a E40255 just happend" --Nobody. @@ -71,4 +62,13 @@ 3. No need to mock the DB, make a "testing" server and beat it hard, just mock FB/Twitter/"Foo-External API" calls. 4. Use something like [Behat](http://behat.org/) to send example JSON bodies and check what sort of responses you get. 5. TEST FOR ERRORS, not just success. Try and trigger every guard statement. 6. If tests aren't automated, they might as well not exist. _Nope, not a copy/paste error._ ### Version your API like an adult 1. Sure throwing a `v1/` subfolder into your `app/controllers` or whatever might seem like a real clever way of doing things, but how are you gonna merge v1.0 tweaks with v1.1 and v2.0? 2. Nginx comes with a handy [Map module](http://wiki.nginx.org/HttpMapModule), map custom Accept headers to a variable. 3. Those headers can look like this: `application/vnd.com.example-v1.0+json`. Gross? [Whatever](https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&docid=-l1lNUV-Sj-RKM&tbnid=Tkz4Pv-XTuQGAM:&ved=0CAUQjRw&url=http%3A%2F%2Fscans-daily.dreamwidth.org%2F3196144.html&ei=jfOaUbTWB4yq0AHM-oCwBw&bvm=bv.46751780,d.dmg&psig=AFQjCNE52ObL3umOX7eH24qcfc3aQkoH2w&ust=1369195783425767). 3. Use this variable to map to a different directory in your virtual host config, and these each have their own Git branch. Something like: "set $api_path api-v$api_version;" followed by a "root /var/www/$api_path/public;" 4. Merge changes upwards to as many codebases that share a common history, don't try and copy and paste changes like a dummy. 5. All rules in this section mean 1.0 could be PHP, 2.0 could be Node (you hipster you) and 3.0 could be Scala (I dont even...) and only your minor versions need to worry about merging changes upwards. -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -37,7 +37,7 @@ 1. Do this. So many people just dump back an "get all this data" response and forget that "N" gets pretty big over time. 2. Add a `"paging"` element, which has a `"next"` or `"previous"` URL if there are more on either side. 3. Dont make the client do math. 4. OUTPUT TOTALS. I'm looking at you Facebook. Why do I have to poll "next" 20 times to manually count() how many friends a specific user has when you obviously know the answer already? GAH! ### Resources are EVERYTHING -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -17,7 +17,7 @@ 1. Don't spend forever trying to make your system output everything under the sun. Sure you can output [lolcat](http://api.flickr.com/services/feeds/photos_public.gne?id=35034363287@N01&lang=en-us&format=lolcode), but you don't need to. 2. Tell your users to send you JSON or XML in the body. Messing around with `application/x-www-form-urlencoded` just for `$_POST['foo']` is no good, especially when any decent framework (like Laravel 4) will allow `Input::json('foo')` anyway. 3. No payload parameters. I've seen APIs accept `application/x-www-form-urlencoded` with a `json={}` parameter. If you think that is a good idea it's time you re-train as a yoga teacher or something, the stress is effecting your judgement. ### Your API needs a shorter memory than... what was I talking about? -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,7 +15,7 @@ ### JSON, XML or shut up 1. Don't spend forever trying to make your system output everything under the sun. Sure you can output [lolcat](http://api.flickr.com/services/feeds/photos_public.gne?id=35034363287@N01&lang=en-us&format=lolcode), but you don't need to. 2. Tell your users to send you JSON or XML in the body. Messing around with `application/x-www-form-urlencoded` just for `$_POST['foo']` is no good, especially when any decent framework (like Laravel 4) will allow `Input::json('foo')` anyway. 3. Payload parameters are for people who need to quit programming. I've seen people accept `application/x-www-form-urlencoded` with a `json={}` parameter. Seriously, re-train as a yoga teacher or something. -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,7 +10,7 @@ 2. Nginx comes with a handy [Map module](http://wiki.nginx.org/HttpMapModule), map custom Accept headers to a variable. 3. Those headers can look like this: `application/vnd.com.example-v1.0+json`. Gross? [Whatever](https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&docid=-l1lNUV-Sj-RKM&tbnid=Tkz4Pv-XTuQGAM:&ved=0CAUQjRw&url=http%3A%2F%2Fscans-daily.dreamwidth.org%2F3196144.html&ei=jfOaUbTWB4yq0AHM-oCwBw&bvm=bv.46751780,d.dmg&psig=AFQjCNE52ObL3umOX7eH24qcfc3aQkoH2w&ust=1369195783425767). 3. Use this variable to map to a different directory in your virtual host config, and these each have their own Git branch. Something like: "set $api_path api-v$api_version;" followed by a "root /var/www/$api_path/public;" 4. Merge changes upwards to as many codebases that share a common history, don't try and copy and paste changes like a dummy. 5. All rules in this section mean 1.0 could be PHP, 2.0 could be Node (you hipster you) and 3.0 could be Scala (I dont even...) and only your minor versions need to worry about merging changes upwards. ### JSON, XML or shut up -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,7 +8,7 @@ 1. Sure throwing a `v1/` subfolder into your `app/controllers` or whatever might seem like a real clever way of doing things, but how are you gonna merge v1.0 tweaks with v1.1 and v2.0? 2. Nginx comes with a handy [Map module](http://wiki.nginx.org/HttpMapModule), map custom Accept headers to a variable. 3. Those headers can look like this: `application/vnd.com.example-v1.0+json`. Gross? [Whatever](https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&docid=-l1lNUV-Sj-RKM&tbnid=Tkz4Pv-XTuQGAM:&ved=0CAUQjRw&url=http%3A%2F%2Fscans-daily.dreamwidth.org%2F3196144.html&ei=jfOaUbTWB4yq0AHM-oCwBw&bvm=bv.46751780,d.dmg&psig=AFQjCNE52ObL3umOX7eH24qcfc3aQkoH2w&ust=1369195783425767). 3. Use this variable to map to a different directory in your virtual host config, and these each have their own Git branch. Something like: "set $api_path api-v$api_version;" followed by a "root /var/www/$api_path/public;" 4. Merge changes upwards to as many codebases that share a common history, don't try and copy and past changes like a dummy. 5. All rules in this section mean 1.0 could be PHP, 2.0 could be Node (you hipster you) and 3.0 could be Scala (I dont even...) and only your minor versions need to worry about merging changes upwards. -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 5 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,9 +7,11 @@ ### Version your API like an adult 1. Sure throwing a `v1/` subfolder into your `app/controllers` or whatever might seem like a real clever way of doing things, but how are you gonna merge v1.0 tweaks with v1.1 and v2.0? 2. Nginx comes with a handy [Map module](http://wiki.nginx.org/HttpMapModule), map custom Accept headers to a variable. 3. Those headers can look like this: `application/vnd.com.kapture.api-v3.1+json`. Gross? [Whatever](https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&docid=-l1lNUV-Sj-RKM&tbnid=Tkz4Pv-XTuQGAM:&ved=0CAUQjRw&url=http%3A%2F%2Fscans-daily.dreamwidth.org%2F3196144.html&ei=jfOaUbTWB4yq0AHM-oCwBw&bvm=bv.46751780,d.dmg&psig=AFQjCNE52ObL3umOX7eH24qcfc3aQkoH2w&ust=1369195783425767). 3. Use this variable to map to a different directory in your virtual host config, and these each have their own Git branch. Something like: "set $api_path api-v$api_version;" followed by a "root /var/www/$api_path/public;" 4. Merge changes upwards to as many codebases that share a common history, don't try and copy and past changes like a dummy. 5. All rules in this section mean 1.0 could be PHP, 2.0 could be Node (you hipster you) and 3.0 could be Scala (I dont even...) and only your minor versions need to worry about merging changes upwards. ### JSON, XML or shut up -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,8 +7,9 @@ ### Version your API like an adult 1. Sure throwing a `v1/` subfolder into your `app/controllers` or whatever might seem like a real clever way of doing things, but how are you gonna merge v1.0 tweaks with v1.1 and v2.0? 2. Use Nginx to pick up a custom Accept header with a version number. 3. Make each API its own codebase in a Git branch, you can merge changes upwards to as many codebases that share a common history. 4. The rule above means 1.0 can be PHP, 2.0 could be Node (you hipster you) and 3.0 could be Scala (I dont even...) and only your minor versions need to worry about merging changes upwards. 1.1, 1.2, 2.1, 3.1 would all be branched off of their x.0 release. ### JSON, XML or shut up -
Phil Sturgeon revised this gist
May 21, 2013 . 1 changed file with 36 additions and 14 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,12 +2,7 @@ 1. If you rename a field, then your users are fucked. Convert with a hardcoded array structure. 1. Most DB drivers [for PHP] will show integers as numeric strings and `false` as `"0"`, so you want to typecast them. 1. Unless you're using an ORM with "hidden" functionality, people will see passwords, salts and all sorts of fancy codes. If you add one and forget to put it in your `$hidden` array then OOPS! ### Version your API like an adult @@ -17,33 +12,60 @@ ### JSON, XML or shut up 1. Don't spend forever trying to make your system output everything under the sun. Sure you can output "lolcat", but you don't need to. 2. Tell your users to send you JSON or XML in the body. Messing around with `application/x-www-form-urlencoded` just for `$_POST['foo']` is no good, especially when any decent framework (like Laravel 4) will allow `Input::json('foo')` anyway. 3. Payload parameters are for people who need to quit programming. I've seen people accept `application/x-www-form-urlencoded` with a `json={}` parameter. Seriously, re-train as a yoga teacher or something. ### Your API needs a shorter memory than... what was I talking about? 1. No state. Your user is an unknown entity, let them tell you who they are with an access token. No guesswork, ignore the IP, let them tell you. 2. Caching should only happen on popular endpoints where there is no user context, and you know its not going to change in the timeframe. 3. OAuth 2 is the shit. A few people wrote ranty arguments about how it's insecure, mostly because they weren't using SSL. So, use SSL. 4. Make sure your OAuth 2 implementation is spec compliant, or you're going to have a bad time. [This one is](https://github.com/php-loep/oauth2-server). ### Background all the things 1. "When the user sends us an image, resize it, upload it to S3 then send an email". Nope. That should be at least one background job, preferably 3. 2. Create an "email" job, a "sms" job and a "APN" job for example, so you can generically send out all sorts of contact stuff from your API, your other jobs, etc without infecting your API with all that stuff. 3. Put your workers on a different server. Your API server is busy enough handling HTTP requests in responses, don't make it thing about anything else. ### Pagination 1. Do this. So many people just dump back an "get all this data" response and forget that "N" gets pretty big over time. 2. Add a `"paging"` element, which has a `"next"` or `"previous"` URL if there are more on either side. 3. Dont make the client do math. 4. OUTPUT COUNTS. I'm looking at you Facebook. Why do I have to poll "next" 20 times to count a users friends? AAAGGHHH!!!1 ### Resources are EVERYTHING 1. You're always either asking for one resource, or multiple. If its one, just return that data as an array. If you've asked for multiple, then return them in a plural parent element (such as "users"). 2. Two resources in different locations should look identical (your iPhone dev will love you for this). This could be `/me/friends` and `/users/5/friends`, or embeded data. 3. If I want multiple resources in one call, then give them to me. `/users/X,Y,Z` in a `"users"` array works nicely. 4. If you ask for multiple and some results exist, shove that in a "users" array. 5. If you ask for multiple but find none, then a 404 makes sense. ### Use the URI sparingly, and correctly 1. Use the query string for paired params instead of `/users/id/5/active/true`. _Your API does not need to be SEO optimised._ 1. `?format=xml` is stupid, use an `Accept: application/xml` header. I added this to the CodeIgniter Rest Server once for lazy people, and now people think it's a thing. It's not. ### Response Codes 1. Give me an actual error message, not just a code. "Oh yay, a E40255 just happend" --Nobody. 2. Use 410 instead of 404 if it's been deleted, or blocked, or rejected. "This content has been removed." > "Um, no clue bro." ### Documentation 1. If you have well written documentation, you get to say RTFM a lot. 2. Versioned API's are easiest to keep up to date, because they don't change (unlike the Facebook API, which might as well be nightly). 3. Use a tool. [Swagger-PHP](https://github.com/wordnik/swagger-ui) + [Swagger-UI](https://github.com/wordnik/swagger-ui) does the trick. ### Testing 1. Write tests, and get Jenkins to automate them. 2. If tests aren't automated, they might as well not exist. 2. Unit-test your components and models and whatnot. 3. No need to mock the DB, make a "testing" server and beat it hard, just mock FB/Twitter/"Foo-External API" calls. 4. Use something like [Behat](http://behat.org/) to send example JSON bodies and check what sort of responses you get. 5. TEST FOR ERRORS, not just success. Try and trigger every guard statement. 6. If tests aren't automated, they might as well not exist. _Nope, not a copy/paste error._ -
Phil Sturgeon revised this gist
Apr 26, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -37,7 +37,7 @@ ### Resources are EVERYTHING 1. You're always either asking for one resource, or multiple. If its one, just return the data. If you've asked for multiple, then return them in a plural parent element (such as "users"). 2. Two resources in different locations should look identical (your iPhone dev will love you for this). This could be `/me/friends` and `/users/5/friends`, or embeded data. 3. If I want multiple resources in one call, then give them to me. `/users/X,Y,Z` in a `"users"` array works nicely. -
Phil Sturgeon revised this gist
Apr 26, 2013 . 1 changed file with 8 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -39,4 +39,11 @@ 1. You're always either asking for one resource, or multiple. If its one, just return the data. If its multiple, then return them in a `"users"` element. 2. Two resources in different locations should look identical (your iPhone dev will love you for this). This could be `/me/friends` and `/users/5/friends`, or embeded data. 3. If I want multiple resources in one call, then give them to me. `/users/X,Y,Z` in a `"users"` array works nicely. ### Documentation 1. If you have well written documentation, you get to say RTFM a lot. 2. Versioned API's are easiest to keep up to date, because they don't change (unlike the Facebook API, which might as well be nightly). 3. Use a tool. [Swagger-PHP](https://github.com/wordnik/swagger-ui) + [Swagger-UI](https://github.com/wordnik/swagger-ui) does the trick. 3. -
Phil Sturgeon revised this gist
Apr 26, 2013 . 1 changed file with 8 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ 1. If you rename a field, then your users are fucked. Convert with a hardcoded array structure. 1. Most DB drivers [for PHP] will show integers as numeric strings and `false` as `"0"`, so you want to typecast them. 1. Unless you're using an ORM with "hidden" functionality, people will see passwords, salts and all sorts of fancy codes. If you add one and forget to put it in your hidden array then OOPS! ### Use the URI sparingly, and correctly 1. Use the query string for paired params instead of `/users/id/5/active/true`. Your API does not need to be SEO optimised. @@ -33,4 +33,10 @@ 1. Do this. So many people just dump back an "get all this data" response and forget that N gets big. 2. Add a `"paging"` element, which has a `"next"` or `"previous"` URL if there are more on either side. 3. Dont make the client do math. ### Resources are EVERYTHING 1. You're always either asking for one resource, or multiple. If its one, just return the data. If its multiple, then return them in a `"users"` element. 2. Two resources in different locations should look identical (your iPhone dev will love you for this). This could be `/me/friends` and `/users/5/friends`, or embeded data. 3. If I want multiple resources in one call, then give them to me. `/users/X,Y,Z` in a `"users"` array works nicely. -
Phil Sturgeon revised this gist
Apr 26, 2013 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -29,3 +29,8 @@ 1. "When the user sends us an image, resize it, upload it to S3 then send an email". Nope. That should be at least one background job, preferably 3. ### Pagination 1. Do this. So many people just dump back an "get all this data" response and forget that N gets big. 2. Add a `"paging"` element, which has a `"next"` or `"previous"` URL if there are more on either side. 3. Dont make the client do math. -
Phil Sturgeon revised this gist
Apr 26, 2013 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,6 +15,11 @@ 1. Use Nginx to pick up a custom Accept header with a version number. 1. Make each API its own codebase in a Git branch, you can merge changes upwards to apply bug fixes to all versions. ### JSON, XML or shut up 1. Don't spend forever trying to make your system output everything under the sun. Sure you can output lolcat, but you don't need to. 2. Tell your users to send you JSON or XML. Messing around with `application/x-www-form-urlencoded` just for `$_POST['foo']` is no good, especially when any decent framework (like Laravel 4) will allow `Input::json('foo')` anyway. ### Your API needs a shorter memory than a chronic stoner 1. No state. Your user is an unknown entity, let them tell you who they are with an access token. -
Phil Sturgeon revised this gist
Apr 26, 2013 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,6 +18,7 @@ ### Your API needs a shorter memory than a chronic stoner 1. No state. Your user is an unknown entity, let them tell you who they are with an access token. 2. Caching should only happen on popular endpoints where there is no user context, and you know its not going to change. ### Background all the things -
Phil Sturgeon revised this gist
Apr 26, 2013 . 1 changed file with 6 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -17,4 +17,9 @@ ### Your API needs a shorter memory than a chronic stoner 1. No state. Your user is an unknown entity, let them tell you who they are with an access token. ### Background all the things 1. "When the user sends us an image, resize it, upload it to S3 then send an email". Nope. That should be at least one background job, preferably 3. -
Phil Sturgeon revised this gist
Apr 26, 2013 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,3 +15,6 @@ 1. Use Nginx to pick up a custom Accept header with a version number. 1. Make each API its own codebase in a Git branch, you can merge changes upwards to apply bug fixes to all versions. ### Your API needs a shorter memory than a chronic stoner 1. No state. Your user is an unknown entity, let them tell you who they are with an access token. -
Phil Sturgeon created this gist
Apr 26, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,17 @@ ### Never Expose DB Results Directly 1. If you rename a field, then your users are fucked. Convert with a hardcoded array structure. 1. Most DB drivers [for PHP] will show integers as numeric strings and `false` as `"0"`, so you want to typecast them. 1. Unless you're using an ORM with "hidden" functionality, people will see passwords, salts and all sorts of fancy codes. If you add one and forget to put it in your hidden array then OOPS! ### Use the URI sparingly, and correctly 1. Use the query string for paired params instead of `/users/id/5/active/true`. Your API does not need to be SEO optimised. 1. `?format=xml` is stupid, use an `Accept: application/xml` header. ### Version your API like an adult 1. Sure throwing a `v1/` subfolder into your `app/controllers` or whatever might seem like a real clever way of doing things, but how are you gonna merge v1.0 tweaks with v1.1 and v2.0? 1. Use Nginx to pick up a custom Accept header with a version number. 1. Make each API its own codebase in a Git branch, you can merge changes upwards to apply bug fixes to all versions.