SlideShare a Scribd company logo
1 of 33
Designing CakePHP plugins for consuming APIs By @neilcrookes for CakeFest2010 www.neilcrookes.com github.com/neilcrookes
Contents Foundations CakePHP plugins, APIs, REST, HTTP, CakePHP HttpSocket, OAuth Design approach Traditional approach, issues with that, my solution Examples
Types of CakePHP plugins Mini apps Provide full functionality you can include in your app e.g. blog, store locator Extenders Extend your app with more functionality e.g. commentable & taggable Enhancers Enhance your apps existing functionality e.g. filter Wrappers Provide functionality to access 3rd party APIs
APIs Source: http://www.programmableweb.com/apis ,[object Object]
My work so far has been mainly consuming RESTful APIs so this presentation and examples will focus on REST
But concepts illustrated in the design approach section later on can be applied to any protocol,[object Object]
HTTP Send request <HTTP verb> <URI> HTTP/1.1 <Header 1 name>: <Header 1 value> ... <optional body> You’ll get some kind of response (hopefully) HTTP/1.1 <Status Code> <Status Message> <Header 1 name>: <Header 1 value> ... <optional body>
Simple HTTP GET Request & Response Request GET http://www.example.com/index.html HTTP/1.1 User-Agent: My Web Browser Response HTTP/1.1 200 OK Content-Type: text/html Content-Length: 70 <html> <head> <title>My Web Page</title> </head> <body> <h1>My Web Page</h1> </body> </html>
Simple HTTP POST Request & Response Request POST http://www.example.com/login HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 38 username=neilcrookes&password=abcd1234 Response HTTP/1.1 301 Moved Permanently Location: http://www.example.com/my_account
CakePHP’s HttpSocket Class cake/libs/http_socket.php ,[object Object],    App::import(‘Core’, ‘HttpSocket’);     $Http = new HttpSocket();     $response = $Http->request(array(     ‘method’ => ‘POST’,       ‘uri’ => array(         ‘host’ => ‘example.com’,         ‘path’ => ‘login’),       ‘body’ => array(         ‘username’ => ‘neilcrookes’,         ‘password’ => ‘abcd1234’))); ,[object Object],[object Object]
OAuth In summary, it allows users of a service (e.g. Twitter) to authorize other parties (i.e. your application) access to their accounts on that service, without sharing their password with the other parties. In reality, it means: a little bit of handshaking between your app and the service provider to get various string tokens redirecting the user to the service in order for them to authorize your app to access their account, so the user only signs in to the service, not your app. the service provides you with a token you can persist and use to make authorized requests to their service on behalf of the user In practice it’s just an extra header line (Authorization header) in the HTTP request which contains some arbitrary parameters e.g. timestamp a token that identifies your application to the API provider a signature string that signs the request and is a hash of various request parameters and the secret tokens you retrieved above Used by e.g. Twitter & Google APIs
HttpSocketOauth Usage example to tweet “Hello world!”: App::import('Vendor', 'HttpSocketOauth'); $Http = new HttpSocketOauth(); $response = $Http->request(array(   'method' => 'POST',   'uri' => array(     'host' => 'api.twitter.com',     'path' => '1/statuses/update.json'),   'auth' => array(     'method' => 'OAuth',     'oauth_token' => <oauth token>,     'oauth_token_secret' => <oauth token secret>,    'oauth_consumer_key' => <oauth consumer key>,     'oauth_consumer_secret' => <oauth consumer secret>),   'body' => array(     'status' => 'Hello world!'))); http://www.neilcrookes.com/2010/04/12/cakephp-oauth-extension-to-httpsocket/ http://github.com/neilcrookes/http_socket_oauth
Contents Foundations CakePHP plugins, APIs, REST, HTTP, CakePHP HttpSocket, OAuth Design approach Traditional approach, issues with that, my solution Examples
Traditional approach: DataSource Complex DataSource containing all the logic Call methods on the DataSource directly from your models or controllersor as implied by the example Twitter DataSource in the cook book: access DataSource methods through your models but include most of the logic in the DataSourcehttp://book.cakephp.org/view/1077/An-Example Works well for simple stuff This is how I started implementing
However... Does not scale well for large APIs Twitter has ~100 API calls available, all with a wide variety of options and parameters. The cook book Twitter DataSource partially implements 2 API calls and is 86 lines Does not exploit built-in CakePHP goodness Callbacks Validation Pagination Does not allow for multiple models (and therefore  multiple schemas) to use the same DataSource Didn’t feel right to me
So what does feel right? What operations are we actually doing? Reading data Creating and updating data Deleting data i.e. Find, save & delete What type of classes in CakePHP provide these methods?
Models Photo by memoflores, available under creative commons http://www.flickr.com/photos/memoflores/ And what should models be?...
FAT! Photo by cstreetus, available under creative commons http://www.flickr.com/photos/cstreetus/ Sorry but every other image I found through searching for “fat models” or “fat ladies” was completely inappropriate ;-)
So if we move our API calls into Model::find(), Model::save() and Model::delete() methods It feels like the right place We’re more familiar with interacting with these We can have lots of simple models classes to achieve scale, separation of concerns and different models can have different validation rules and schemas and we can collect them together in a plugin But...
But what about CakePHP goodness? Triggering callbacks beforeFind(), afterFind(), beforeSave(), afterSave(), beforeValidate(), beforeDelete(), afterDelete() Triggering validation Handling custom find types If we made the API calls directly in these methods and returned the response, to exploit this excellent built-in additional CakePHP functionality we’d have to trigger/code them manually We’d be duplicating loads of code from CakePHP’s core Model class. Not very DRY
To understand the solution, we must understand CakePHP Model internals Model methods like find(), save() and delete() accept various params such as conditions, data to save etc Handle custom find types for find() only Handle validation for save() only Trigger the before*() callbacks Call create(), read(), update() or delete() on that model’s DataSource Trigger the after*() callbacks Return the result
So what’s my solution for designing CakePHP plugins for consuming APIs? Plugin containing one model for each type of resource in the API e.g. TwitterStatus or YouTubeVideo Models implement find() (or actually more commonly just CakePHP custom find types), save() and delete() methods as appropriate These methods set the details of the request, i.e. The array that represents an HTTP request that HttpSocket::request() methods expects (as we saw earlier in this presentation) in a request property of your model, then calls the same method on the parent object i.e. Model. Cont...
Solution continued CakePHP Model class handles validation and custom find types, triggers callbacks etc then calls create(), read(), update() or delete() on the child model’s (your model’s) DataSource, and passes the model object Your model’s useDbConfig property should be set to a custom DataSource that you also include in your plugin Your DataSource implements the appropriate CRUD method(s) and issues the API call described in the model’s requestproperty, and returns the results
Hmmm, sounds complicated It’s not I’ve written a REST DataSource you can use (see later) All you have to do is create a model that has find() or save() methods, in which you set a request property to an array expected by HttpSocket::request() and call the same method on the parent.
E.g. Creating a tweet <?php class TwitterStatus extends AppModel {   public function save($data = null) {     $this->request = array(       'uri' => array(         'host' => 'api.twitter.com',         'path' => '1/statuses/update.json'),       'body' => array(         'status' => $data['TwitterStatus']['text']));     return parent::save($data);   } } ?>
Which you call like this ClassRegistry::init('Twitter.TwitterStatus')->save(array(   'TwitterStatus' => array(     'text' => “Hello world!”) )); ... from anywhere you like in your CakePHP application, e.g. In your Post model afterSave() method, thus automatically creating a tweet every time you create a new post.
RestSource http://www.neilcrookes.com/2010/06/01/rest-datasource-plugin-for-cakephp/ http://github.com/neilcrookes/CakePHP-ReST-DataSource-Plugin You can set your model’s useDbConfigparam to this DataSource, or you can write your own DataSource that extends this one E.g. Override RestSource::request() to add in the host key in the $model->request property if it’s the same for all API calls, then call parent::(request)
This diagram illustrates the flow through the methods an classes involved in creating a tweet https://docs.google.com/drawings/edit?id=1Aht7huICl9bhl2hWRdM0VdoaBePpJ0kXkceyQpAR8os&hl=en_GB&authkey=CISSqJkN
In summary By designing plugins like this you’re providing Simple (1 line) method calls to API functions That are familiar to all CakePHP bakers And easy to document You also get to exploit CakePHP goodness such as validation and callbacks etc You can have multiple models, one for each resource type on the API, each with it’s own schema (which the FormHelper uses) and validation rules
Contents Foundations CakePHP plugins, APIs, REST, HTTP, CakePHP HttpSocket, OAuth Design approach Traditional approach, issues with that, my solution Examples
Examples YouTube Twitter
Uploading a YouTube Video – you do ClassRegistry::init('Gdata.YouTubeVideo')->save(array(   'YouTubeVideo' => array(     'title' => 'Flying into Chicago Airport',     'description' => 'Filmed through the plane window coming in over the lake',     'category' => 'Travel',     'keywords' => 'Chicago, Plane, Lake, Skyline',     'rate' => 'allowed',     'comment' => 'allowed',     'commentVote' => 'allowed',     'videoRespond' => 'allowed',     'embed' => 'allowed',     'syndicate' => 'allowed',     'private' => 1,     'file' => array(       'name' => 'chicago 1 060.AVI',       'type' => 'video/avi',       'tmp_name' => 'C:indowsemphp6D66.tmp',       'error' => 0,       'size' => 5863102))));
Uploading a YouTube Video – plugin creates POST /feeds/api/users/default/uploads HTTP/1.1 Host: uploads.gdata.youtube.com Connection: close User-Agent: CakePHP Content-Type: multipart/related; boundary="Next_Part_4c801b22-52e8-4c70-961b-0534fba3b5b1“ Slug: chicago 1 060.AVI Gdata-Version: 2 X-Gdata-Key: key=<my developer key> Authorization: OAuth oauth_version="1.0",oauth_signature_method="HMAC-SHA1",oauth_consumer_key="anonymous",oauth_token=“<my oauth token>",oauth_nonce="fa4b6fc350e19f675f2e5660657e643c",oauth_timestamp="1283463971",oauth_signature="3fIXJ%2BmdV6KLk4zJYszR7M90lIg%3D“ Content-Length: 5864289 --Next_Part_4c801b22-52e8-4c70-961b-0534fba3b5b1 Content-Type: application/atom+xml; charset=UTF-8 <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">   <media:group>     <media:title type="plain">Flying into Chicago Airport</media:title>     <media:description type="plain">Filmed through the plane window, shows coming in over the lake</media:description>     <media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">Travel</media:category>     <media:keywords>Chicago, Plane, Lake, Skyline</media:keywords>     <yt:private/>   </media:group>   <yt:accessControl action="rate" permission="allowed"/>   <yt:accessControl action="comment" permission="allowed"/>   <yt:accessControl action="commentVote" permission="allowed"/><   <yt:accessControl action="videoRespond" permission="allowed"/>   <yt:accessControl action="embed" permission="allowed"/>   <yt:accessControl action="syndicate" permission="allowed"/> </entry>  --Next_Part_4c801b22-52e8-4c70-961b-0534fba3b5b1  Content-Type: video/avi Content-Transfer-Encoding: binary <binary file data>

More Related Content

What's hot

4 introduction-php-mvc-cakephp-m4-controllers-slides
4 introduction-php-mvc-cakephp-m4-controllers-slides4 introduction-php-mvc-cakephp-m4-controllers-slides
4 introduction-php-mvc-cakephp-m4-controllers-slidesMasterCode.vn
 
ACL in CodeIgniter
ACL in CodeIgniterACL in CodeIgniter
ACL in CodeIgnitermirahman
 
XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話Takehito Tanabe
 
6 introduction-php-mvc-cakephp-m6-views-slides
6 introduction-php-mvc-cakephp-m6-views-slides6 introduction-php-mvc-cakephp-m6-views-slides
6 introduction-php-mvc-cakephp-m6-views-slidesMasterCode.vn
 
Request dispacther interface ppt
Request dispacther interface pptRequest dispacther interface ppt
Request dispacther interface pptTaha Malampatti
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationAbdul Malik Ikhsan
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST APICaldera Labs
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVCIndicThreads
 
Building Applications Using Ajax
Building Applications Using AjaxBuilding Applications Using Ajax
Building Applications Using Ajaxs_pradeep
 
An introduction to Laravel Passport
An introduction to Laravel PassportAn introduction to Laravel Passport
An introduction to Laravel PassportMichael Peacock
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful CodeGreggPollack
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswanivvaswani
 
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Caldera Labs
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 

What's hot (20)

4 introduction-php-mvc-cakephp-m4-controllers-slides
4 introduction-php-mvc-cakephp-m4-controllers-slides4 introduction-php-mvc-cakephp-m4-controllers-slides
4 introduction-php-mvc-cakephp-m4-controllers-slides
 
REST API Laravel
REST API LaravelREST API Laravel
REST API Laravel
 
ACL in CodeIgniter
ACL in CodeIgniterACL in CodeIgniter
ACL in CodeIgniter
 
Slim Framework
Slim FrameworkSlim Framework
Slim Framework
 
Web api
Web apiWeb api
Web api
 
XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話XamarinとAWSをつないでみた話
XamarinとAWSをつないでみた話
 
6 introduction-php-mvc-cakephp-m6-views-slides
6 introduction-php-mvc-cakephp-m6-views-slides6 introduction-php-mvc-cakephp-m6-views-slides
6 introduction-php-mvc-cakephp-m6-views-slides
 
Request dispacther interface ppt
Request dispacther interface pptRequest dispacther interface ppt
Request dispacther interface ppt
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept Implementation
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST API
 
Day01 api
Day01   apiDay01   api
Day01 api
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVC
 
Building Applications Using Ajax
Building Applications Using AjaxBuilding Applications Using Ajax
Building Applications Using Ajax
 
An introduction to Laravel Passport
An introduction to Laravel PassportAn introduction to Laravel Passport
An introduction to Laravel Passport
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful Code
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
 
Spring Mvc Rest
Spring Mvc RestSpring Mvc Rest
Spring Mvc Rest
 
Zend framework
Zend frameworkZend framework
Zend framework
 
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
Single Page Web Apps As WordPress Admin Interfaces Using AngularJS & The Word...
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 

Similar to Designing CakePHP plugins for consuming APIs

Practical catalyst
Practical catalystPractical catalyst
Practical catalystdwm042
 
En story of cakephp2.0
En story of cakephp2.0En story of cakephp2.0
En story of cakephp2.0Hiroki Shimizu
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHPKing Foo
 
ASP.NET MVC introduction
ASP.NET MVC introductionASP.NET MVC introduction
ASP.NET MVC introductionTomi Juhola
 
Php interview questions
Php interview questionsPhp interview questions
Php interview questionssekar c
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's CodeWildan Maulana
 
Webservices in SalesForce (part 1)
Webservices in SalesForce (part 1)Webservices in SalesForce (part 1)
Webservices in SalesForce (part 1)Mindfire Solutions
 
OpenSocial Intro
OpenSocial IntroOpenSocial Intro
OpenSocial IntroPamela Fox
 
Compass Framework
Compass FrameworkCompass Framework
Compass FrameworkLukas Vlcek
 
Http programming in play
Http programming in playHttp programming in play
Http programming in playKnoldus Inc.
 
RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座Li Yi
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplicationolegmmiller
 
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...Guillaume Laforge
 
Intro To Mvc Development In Php
Intro To Mvc Development In PhpIntro To Mvc Development In Php
Intro To Mvc Development In Phpfunkatron
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 

Similar to Designing CakePHP plugins for consuming APIs (20)

Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
 
En story of cakephp2.0
En story of cakephp2.0En story of cakephp2.0
En story of cakephp2.0
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHP
 
Manish
ManishManish
Manish
 
Php
PhpPhp
Php
 
ASP.NET MVC introduction
ASP.NET MVC introductionASP.NET MVC introduction
ASP.NET MVC introduction
 
CGI Presentation
CGI PresentationCGI Presentation
CGI Presentation
 
Php interview questions
Php interview questionsPhp interview questions
Php interview questions
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's Code
 
Webservices in SalesForce (part 1)
Webservices in SalesForce (part 1)Webservices in SalesForce (part 1)
Webservices in SalesForce (part 1)
 
OpenSocial Intro
OpenSocial IntroOpenSocial Intro
OpenSocial Intro
 
Php frameworks
Php frameworksPhp frameworks
Php frameworks
 
Compass Framework
Compass FrameworkCompass Framework
Compass Framework
 
Http programming in play
Http programming in playHttp programming in play
Http programming in play
 
RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座RESTful SOA - 中科院暑期讲座
RESTful SOA - 中科院暑期讲座
 
Java Servlets
Java ServletsJava Servlets
Java Servlets
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
 
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
JavaOne 2008 - TS-5793 - Groovy and Grails, changing the landscape of Java EE...
 
Intro To Mvc Development In Php
Intro To Mvc Development In PhpIntro To Mvc Development In Php
Intro To Mvc Development In Php
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 

Recently uploaded

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 

Designing CakePHP plugins for consuming APIs

  • 1. Designing CakePHP plugins for consuming APIs By @neilcrookes for CakeFest2010 www.neilcrookes.com github.com/neilcrookes
  • 2. Contents Foundations CakePHP plugins, APIs, REST, HTTP, CakePHP HttpSocket, OAuth Design approach Traditional approach, issues with that, my solution Examples
  • 3. Types of CakePHP plugins Mini apps Provide full functionality you can include in your app e.g. blog, store locator Extenders Extend your app with more functionality e.g. commentable & taggable Enhancers Enhance your apps existing functionality e.g. filter Wrappers Provide functionality to access 3rd party APIs
  • 4.
  • 5. My work so far has been mainly consuming RESTful APIs so this presentation and examples will focus on REST
  • 6.
  • 7. HTTP Send request <HTTP verb> <URI> HTTP/1.1 <Header 1 name>: <Header 1 value> ... <optional body> You’ll get some kind of response (hopefully) HTTP/1.1 <Status Code> <Status Message> <Header 1 name>: <Header 1 value> ... <optional body>
  • 8. Simple HTTP GET Request & Response Request GET http://www.example.com/index.html HTTP/1.1 User-Agent: My Web Browser Response HTTP/1.1 200 OK Content-Type: text/html Content-Length: 70 <html> <head> <title>My Web Page</title> </head> <body> <h1>My Web Page</h1> </body> </html>
  • 9. Simple HTTP POST Request & Response Request POST http://www.example.com/login HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 38 username=neilcrookes&password=abcd1234 Response HTTP/1.1 301 Moved Permanently Location: http://www.example.com/my_account
  • 10.
  • 11. OAuth In summary, it allows users of a service (e.g. Twitter) to authorize other parties (i.e. your application) access to their accounts on that service, without sharing their password with the other parties. In reality, it means: a little bit of handshaking between your app and the service provider to get various string tokens redirecting the user to the service in order for them to authorize your app to access their account, so the user only signs in to the service, not your app. the service provides you with a token you can persist and use to make authorized requests to their service on behalf of the user In practice it’s just an extra header line (Authorization header) in the HTTP request which contains some arbitrary parameters e.g. timestamp a token that identifies your application to the API provider a signature string that signs the request and is a hash of various request parameters and the secret tokens you retrieved above Used by e.g. Twitter & Google APIs
  • 12. HttpSocketOauth Usage example to tweet “Hello world!”: App::import('Vendor', 'HttpSocketOauth'); $Http = new HttpSocketOauth(); $response = $Http->request(array( 'method' => 'POST', 'uri' => array( 'host' => 'api.twitter.com', 'path' => '1/statuses/update.json'), 'auth' => array( 'method' => 'OAuth', 'oauth_token' => <oauth token>, 'oauth_token_secret' => <oauth token secret>, 'oauth_consumer_key' => <oauth consumer key>, 'oauth_consumer_secret' => <oauth consumer secret>), 'body' => array( 'status' => 'Hello world!'))); http://www.neilcrookes.com/2010/04/12/cakephp-oauth-extension-to-httpsocket/ http://github.com/neilcrookes/http_socket_oauth
  • 13. Contents Foundations CakePHP plugins, APIs, REST, HTTP, CakePHP HttpSocket, OAuth Design approach Traditional approach, issues with that, my solution Examples
  • 14. Traditional approach: DataSource Complex DataSource containing all the logic Call methods on the DataSource directly from your models or controllersor as implied by the example Twitter DataSource in the cook book: access DataSource methods through your models but include most of the logic in the DataSourcehttp://book.cakephp.org/view/1077/An-Example Works well for simple stuff This is how I started implementing
  • 15. However... Does not scale well for large APIs Twitter has ~100 API calls available, all with a wide variety of options and parameters. The cook book Twitter DataSource partially implements 2 API calls and is 86 lines Does not exploit built-in CakePHP goodness Callbacks Validation Pagination Does not allow for multiple models (and therefore multiple schemas) to use the same DataSource Didn’t feel right to me
  • 16. So what does feel right? What operations are we actually doing? Reading data Creating and updating data Deleting data i.e. Find, save & delete What type of classes in CakePHP provide these methods?
  • 17. Models Photo by memoflores, available under creative commons http://www.flickr.com/photos/memoflores/ And what should models be?...
  • 18. FAT! Photo by cstreetus, available under creative commons http://www.flickr.com/photos/cstreetus/ Sorry but every other image I found through searching for “fat models” or “fat ladies” was completely inappropriate ;-)
  • 19. So if we move our API calls into Model::find(), Model::save() and Model::delete() methods It feels like the right place We’re more familiar with interacting with these We can have lots of simple models classes to achieve scale, separation of concerns and different models can have different validation rules and schemas and we can collect them together in a plugin But...
  • 20. But what about CakePHP goodness? Triggering callbacks beforeFind(), afterFind(), beforeSave(), afterSave(), beforeValidate(), beforeDelete(), afterDelete() Triggering validation Handling custom find types If we made the API calls directly in these methods and returned the response, to exploit this excellent built-in additional CakePHP functionality we’d have to trigger/code them manually We’d be duplicating loads of code from CakePHP’s core Model class. Not very DRY
  • 21. To understand the solution, we must understand CakePHP Model internals Model methods like find(), save() and delete() accept various params such as conditions, data to save etc Handle custom find types for find() only Handle validation for save() only Trigger the before*() callbacks Call create(), read(), update() or delete() on that model’s DataSource Trigger the after*() callbacks Return the result
  • 22. So what’s my solution for designing CakePHP plugins for consuming APIs? Plugin containing one model for each type of resource in the API e.g. TwitterStatus or YouTubeVideo Models implement find() (or actually more commonly just CakePHP custom find types), save() and delete() methods as appropriate These methods set the details of the request, i.e. The array that represents an HTTP request that HttpSocket::request() methods expects (as we saw earlier in this presentation) in a request property of your model, then calls the same method on the parent object i.e. Model. Cont...
  • 23. Solution continued CakePHP Model class handles validation and custom find types, triggers callbacks etc then calls create(), read(), update() or delete() on the child model’s (your model’s) DataSource, and passes the model object Your model’s useDbConfig property should be set to a custom DataSource that you also include in your plugin Your DataSource implements the appropriate CRUD method(s) and issues the API call described in the model’s requestproperty, and returns the results
  • 24. Hmmm, sounds complicated It’s not I’ve written a REST DataSource you can use (see later) All you have to do is create a model that has find() or save() methods, in which you set a request property to an array expected by HttpSocket::request() and call the same method on the parent.
  • 25. E.g. Creating a tweet <?php class TwitterStatus extends AppModel { public function save($data = null) { $this->request = array( 'uri' => array( 'host' => 'api.twitter.com', 'path' => '1/statuses/update.json'), 'body' => array( 'status' => $data['TwitterStatus']['text'])); return parent::save($data); } } ?>
  • 26. Which you call like this ClassRegistry::init('Twitter.TwitterStatus')->save(array( 'TwitterStatus' => array( 'text' => “Hello world!”) )); ... from anywhere you like in your CakePHP application, e.g. In your Post model afterSave() method, thus automatically creating a tweet every time you create a new post.
  • 27. RestSource http://www.neilcrookes.com/2010/06/01/rest-datasource-plugin-for-cakephp/ http://github.com/neilcrookes/CakePHP-ReST-DataSource-Plugin You can set your model’s useDbConfigparam to this DataSource, or you can write your own DataSource that extends this one E.g. Override RestSource::request() to add in the host key in the $model->request property if it’s the same for all API calls, then call parent::(request)
  • 28. This diagram illustrates the flow through the methods an classes involved in creating a tweet https://docs.google.com/drawings/edit?id=1Aht7huICl9bhl2hWRdM0VdoaBePpJ0kXkceyQpAR8os&hl=en_GB&authkey=CISSqJkN
  • 29. In summary By designing plugins like this you’re providing Simple (1 line) method calls to API functions That are familiar to all CakePHP bakers And easy to document You also get to exploit CakePHP goodness such as validation and callbacks etc You can have multiple models, one for each resource type on the API, each with it’s own schema (which the FormHelper uses) and validation rules
  • 30. Contents Foundations CakePHP plugins, APIs, REST, HTTP, CakePHP HttpSocket, OAuth Design approach Traditional approach, issues with that, my solution Examples
  • 32. Uploading a YouTube Video – you do ClassRegistry::init('Gdata.YouTubeVideo')->save(array( 'YouTubeVideo' => array( 'title' => 'Flying into Chicago Airport', 'description' => 'Filmed through the plane window coming in over the lake', 'category' => 'Travel', 'keywords' => 'Chicago, Plane, Lake, Skyline', 'rate' => 'allowed', 'comment' => 'allowed', 'commentVote' => 'allowed', 'videoRespond' => 'allowed', 'embed' => 'allowed', 'syndicate' => 'allowed', 'private' => 1, 'file' => array( 'name' => 'chicago 1 060.AVI', 'type' => 'video/avi', 'tmp_name' => 'C:indowsemphp6D66.tmp', 'error' => 0, 'size' => 5863102))));
  • 33. Uploading a YouTube Video – plugin creates POST /feeds/api/users/default/uploads HTTP/1.1 Host: uploads.gdata.youtube.com Connection: close User-Agent: CakePHP Content-Type: multipart/related; boundary="Next_Part_4c801b22-52e8-4c70-961b-0534fba3b5b1“ Slug: chicago 1 060.AVI Gdata-Version: 2 X-Gdata-Key: key=<my developer key> Authorization: OAuth oauth_version="1.0",oauth_signature_method="HMAC-SHA1",oauth_consumer_key="anonymous",oauth_token=“<my oauth token>",oauth_nonce="fa4b6fc350e19f675f2e5660657e643c",oauth_timestamp="1283463971",oauth_signature="3fIXJ%2BmdV6KLk4zJYszR7M90lIg%3D“ Content-Length: 5864289 --Next_Part_4c801b22-52e8-4c70-961b-0534fba3b5b1 Content-Type: application/atom+xml; charset=UTF-8 <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007"> <media:group> <media:title type="plain">Flying into Chicago Airport</media:title> <media:description type="plain">Filmed through the plane window, shows coming in over the lake</media:description> <media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">Travel</media:category> <media:keywords>Chicago, Plane, Lake, Skyline</media:keywords> <yt:private/> </media:group> <yt:accessControl action="rate" permission="allowed"/> <yt:accessControl action="comment" permission="allowed"/> <yt:accessControl action="commentVote" permission="allowed"/>< <yt:accessControl action="videoRespond" permission="allowed"/> <yt:accessControl action="embed" permission="allowed"/> <yt:accessControl action="syndicate" permission="allowed"/> </entry> --Next_Part_4c801b22-52e8-4c70-961b-0534fba3b5b1 Content-Type: video/avi Content-Transfer-Encoding: binary <binary file data>