Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Your API Sucks

Your API Sucks

A presentation to be given by Ben Edmunds at CICONF 2012 on RESTful API Design and Implementation with CodeIgniter.

Ben Edmunds

May 09, 2012
Tweet

More Decks by Ben Edmunds

Other Decks in Technology

Transcript

  1. Who Am I Ben Edmunds @benedmunds http://benedmunds.com Build and lead

    development teams >10 years of experience in the industry Specialize in PHP development
  2. Who Am I Ben Edmunds @benedmunds http://benedmunds.com Ion Auth http://github.com/benedmunds/CodeIgniter-Ion-Auth

    General http://github.com/benedmunds Open Source Contributions http://appstucco.com
  3. Who Am I Personal: From Phenix City, AL Married for

    6 years Work for Kforce Government Solutions Co-Founder of AppStucco Tech Focus: PHP (CodeIgniter, Laravel) Javascript (Node.js, Express, Phonegap) Databases (MySQL, PostGreSQL, MongoDB) Ben Edmunds @benedmunds http://benedmunds.com
  4. What is REST? Most widely used data format is JSON

    Javascript Object Notation { key: ‘value’, anotherKey: ‘value2’ }
  5. What is REST? JSON usage in Javascript = familiar var

    object = { key: ‘value’, anotherKey: ‘value2’ };
  6. What is REST? Outputs {key: ‘value’} PHP echo json_encode(array( ‘key’

    => ‘value’ )); JSON encoding is supported in most languages
  7. What is REST? Outputs array( ‘key’ => ‘value’ ) $json_data

    = “{key: ‘value’}”; print_r(json_decode($json_data)); JSON decoding is just as simple PHP
  8. API Design Different Opinions PUT = create (idempotent) POST =

    create (unknown resource) PUT = update (resource is known) Put vs Post
  9. API Design URL endpoints represent their data Objects map to

    plural URLs A single Object maps to a singular URL Common actions across most objects
  10. API Design Creating If you know all of the data

    (including the ID) PUT http://site.com/api/status/1234
  11. API Design Creating If you know all of the data

    (including the ID) PUT http://site.com/api/status/1234 No matter how many times you send this data only one resource should ever be created Idempotent
  12. API Design Creating If you know all of the data

    (including the ID) PUT http://site.com/api/status/1234 { id: 1234, retweeted: false, active: true }
  13. API Design Creating If you don’t know all of the

    data POST http://site.com/api/status
  14. API Design Creating If you don’t know all of the

    data POST http://site.com/api/status Each time you post this data a new resource should be created Unique
  15. API Design Creating If you don’t know all of the

    data POST http://site.com/api/status { retweeted: false, active: true }
  16. API Design Reading Get all of the statuses that have

    been retweeted and are active - GET http://site.com/api/statuses /retweeted/true/active/true
  17. API Design Update We know all of the identifying information

    so we PUT updates {active: true} PUT http://site.com/api/status/1234
  18. API Design Relationships Get the user that posted a status

    GET http://site.com/api/status/1234/user
  19. API Design How to handle versioning? Route newest API through

    http://api.site.com OR http://site.com/api GET http://site.com/api/v2/statuses GET http://site.com/api/statuses =
  20. Implementation application - config - controllers - models - views

    - ... system - index.php Directory structure
  21. Implementation application - config - rest.php controllers - models -

    views - ... system - index.php Setup the config
  22. Implementation application - config - controllers - api - v1.php

    models - views - ... system - index.php Create the controller
  23. Implementation GET /status/id/1 = function status_get function status_get() { if

    (!$this->get('id')) { $this->response(array('error' => 'ID is required'), 404); } $status = $this->status_m->get( $this->get('id') ); if ($status) { $this->response($status, 200); } else { $this->response(array('error' => 'Status not be found'), 404); } }
  24. Implementation GET /status/id/1 if (!$this->get('id')) { $this->response( array( ‘success’ =>

    FALSE, 'error' => 'ID is required' ), 404); } Require the ID param. Send an error response.
  25. Implementation GET /status/id/1 $status = $this->status_m->get( $this->get('id') ); if ($status)

    { $response = array( ‘success’ => TRUE, ‘status‘ => $status ); $this->response($response, 200); } else { $this->response(array( ‘success’ => FALSE, 'error' => 'Status not be found' ), 404); } Get the status. Pass the status in the response. Else send an error response.
  26. Implementation function status_post() { $data = array( ‘user_id’ => $this->post(‘user_id’),

    ‘text‘ => $this->post(‘text’), ); $status_id = $this->status_m->insert($data); if ($status) { $this->response(array( 'success' => TRUE, 'id' => $status_id ), 200); } //error goes here } POST /status = function status_post
  27. Implementation function status_post() { $id = $this->put(‘id’); $data = array(

    ‘user_id’ => $this->put(‘user_id’), ‘text‘ => $this->put(‘text’), ); $updated = $this->status_m->update($id, $data); if ($updated) { $this->response(array( 'success' => TRUE ), 200); } //error goes here } PUT /status = function status_put
  28. Implementation function status_delete() { $id = $this->delete(‘id’); $deleted = $this->status_m->delete($id);

    if ($deleted) { $this->response(array( 'success' => TRUE ), 200); } //error goes here } DELETE /status = function status_delete