SlideShare a Scribd company logo
1 of 33
Download to read offline
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

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
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
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
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
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
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
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
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Nikki Chapple
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sectoritnewsafrica
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 

Recently uploaded (20)

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
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
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
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
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...
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
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
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 

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>