SlideShare a Scribd company logo
API Design in PHP
          David Sklar
  Software Architect, Ning Inc.
      david@ninginc.com

    Zend Conference 2007
Ning Platform
Ning Platform
Ning

• PHP API provides interface to our platform
  REST APIs
• Live since August 2005 (with 5.0.4)
• Recent upgrade to 5.2.3
• In use in all 108,000+ networks on the
  platform
Ning

• Migration from XMLRPC to REST in 2005/6
• APIs used for content storage, user profile
  management, tagging, search, video
  transcoding, messaging, ...
• PHP (using APIs) runs in a hosted
  environment
API: XN_Content
<?php
$dinner = XN_Content::create('Meal');
$dinner->title = 'Salt Baked Combo';
$dinner->my->protein = 'seafood';
$dinner->my->ingredients = 
               array('shrimp','scallops','squid');
$dinner->save();
?>
PHP ➠ REST
POST /xn/atom/1.0/content
Content-Type: text/xml;charset=UTF-8

<entry xmlns="http://www.w3.org/2005/Atom"
       xmlns:xn="http://www.ning.com/atom/1.0"
       xmlns:my="http://afternoonsnack.ning.com/xn/atom/1.0">
 <xn:type>Meal</xn:type>
 <title type="text">Salt Baked Combo</title>
 <my:protein type='string'>seafood</my:protein>
 <my:ingredients type='string'>
   <xn:value>shrimp</xn:value><xn:value>scallops</xn:value>
   <xn:value>squid</xn:value>
 </my:ingredients>
</entry>
HTTP/1.1 200 OK
                      PHP ➠ REST
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:xn="http://www.ning.com/atom/1.0">
 <xn:size>1</xn:size>
 <updated>2007-08-28T22:11:47.420Z</updated>
 <entry xmlns:my="http://afternoonsnack.ning.com/xn/atom/1.0">
  <id>http://afternoonsnack.ning.com/502068:Meal:122</id>
  <xn:type>Meal</xn:type>
  <xn:id>502068:Meal:122</xn:id>
  <title type="text">Salt Baked Combo</title>
  <published>2007-08-28T22:11:47.414Z</published>
  <updated>2007-08-28T22:11:47.414Z</updated>
  <link rel="alternate"
        href="http://afternoonsnack.ning.com/xn/detail/502068:Meal:122" />
  <my:protein type="string">seafood</my:protein>
  ...
 </entry>
</feed>
Design Priorities

• Promote predictability, modularity, stability
• Choose human performance over computer
  performance
• Make efficiency easy, make inefficiency hard/
  impossible
At the start...

• Write code before you write the API
• Use cases, Use cases, Use cases
• Names matter (but don’t discuss them
  forever)
Use the API before it
            exists
Sketch out what you want to do....
Use Cases First!


• What does the API need to do?
• (Not “what could it do?”)
Need-driven
        Development

• Adding is easy. Removing is hard.
• You have lots of freedom with arguments
• Accessors provide insulation
Arguments
Long parameter lists are toxic:
<?php

function save($data, $flavor = null, $scope = null,
              $commit = null, $cascade = null,
              $permissions = null) {
    if (is_null($flavor))      { $flavor = 'quick'; }
    if (is_null($scope))       { $scope = 'global'; }
    if (is_null($commit))      { $commit = true; }
    if (is_null($cascade))     { $cascade = false; }
    if (is_null($permissions)) { $permissions = 0755; }
    // ...
}
Bread Stuffing
Bread Stuffing
What does this do?
<?php

save($data, null, null, true, false);

?>
How about this?
<?php

save($data, array('scope' => 'local'));

?>
Ahh, much better:
<?php

function save($data, $paramsOrFlavor = null,
               $scope = null, $commit = null,
              $cascade = null, $permissions = null){
    if (is_array($paramsOrFlavor)) {
        // ...
    }
    else {
        // ...
    }
}
Fun with __get() and __set()
public function __get($name) {
  switch ($name) {
    case self::screenName:
      return $this->_screenName;
    case self::fullName:
      return $this->_fullName;
    case self::uploadEmailAddress:
      $this->_lazyLoad('uploadEmailAddress');
      return $this->_uploadEmailAddress;
    case 'description':
      // ...
}
Static ‘n’ Dynamic Analysis



• find + grep
• tokenizer
• hooks + logging
find + grep
find . -name *.php -exec grep -H '::load('

   • easy
   • fast
   • mostly correct: watch out for dynamic
     variable names, text collision, etc.
tokenizer


• php-specific knowledge, but...
• can be slower
• need to write custom rules and parsing
$tokens = array(T_INCLUDE => 0, T_INCLUDE_ONCE => 0,
                T_REQUIRE => 0, T_REQUIRE_ONCE => 0);

foreach (new PhpFilterIterator(new RecursiveIteratorIterator(
         new RecursiveDirectoryIterator($root))) as $f) {
  $muncher = new Tokenmunch(file_get_contents($f));
  foreach ($muncher as $token) {
    if (array_key_exists($token[0], $tokens)) {
      $tokens[$token[0]]++;
      $startOfLine = $muncher->scanBackFor(T_WHITESPACE,"/n/");
      $startOfBlock = $muncher->scanBackFor(T_OPEN_TAG);
      $previousComment = $muncher->scanBackFor(T_COMMENT,"/n$/");
      $startPosition = max($startOfLine, $startOfBlock, $previousComment) +1;
      $endOfLine = $muncher->scanForwardFor(T_STRING, '/^;$/');
      $slice =  $muncher->sliceAsString($startPosition,
                                       $endOfLine - $startPosition+1);
      print trim($slice) . "n";
    }
  }
}
Hooks + Logging


• need to instrument the API beforehand
• watch out for performance overhead
API for the API: XN_Event
class XN_Event {
    /**
     * Fire an event with optional arguments
     *
     * @param string $event
     * @param array $args optional arguments to pass to listeners
     */
    public static function fire($event, $args = null);
                                          
    /**
     * Listen for an event
     *
     * @param string $event
     * @param callback $callback Function to run when the event is fired
     * @param array $args optional arguments to pass to the callback
     * @return string
     */
    public static function listen($event, $callback, $args = null);
}
XN_Event in Use
XN_Content::save() calls:
XN_Event::fire('xn/content/save/before', array($this));
// do the save
XN_Event::fire('xn/content/save/after', array($this));



This has been very useful for cache expiration.
Late Static Binding Workaround
Class name registry for static inheritance:

 W_Cache::putClass('app','XG_App');

 // ... time passes ...

 $className = W_Cache::getClass($role);
 $retval = call_user_func_array(
              array($className, $method),
              $args
           );
Names Matter


• Namespacing / collisions
• Versioning
Namespacing

• At Ning, “XN” means “hands off”
 • class names
 • property names
 • xml namespace prefixes
Versioning

• YourClass and YourClass2...sigh.
• Using include_path and auto_prepend_file
• Version number in REST URLs:
 http://app.ning.com/xn/atom/1.0/content/...
Docblocks:Yay!
/** It’s easy to generate human(-ish)
  * readable documentation from
  * docblocks. (@see PHPDocumentor,
  * @see doxygen)
  *
  * And the documentation is close
  * to the code.
  */
public function debigulator() {
}
Docblocks: Boo!
/** What about examples and tutorials
  * and all of the other thing that
  * are not method or class
  * specific?
  *
  * Is this documentation up to date
  * with the @version of the code?
  */
public function rebigulator() {
}
Too Much Sugar
// "System" Attribute
$content->title = 'Duck with Pea Shoots';

// "Developer" Attribute
$content->my->meat = true;
Non-literal Names..!
$attrs = array('title','my->meat');

foreach ($attrs as $attr) {
    print "$attr is " . $content->$attr;
}




            ☹
Alternatives

OK $content->title    and $content->my_flavor;

OK $content->xn_title and $content->flavor;

NO $content['title']  and $content->flavor;
Testing
      &
Code Coverage
The extent of your
        test suite
          is the
strength of your contract
     with your users.
Tools are secondary.

Discipline is primary.
Tools

• SimpleTest
 •   http://www.lastcraft.com/simple_test.php

• PHPUnit
 •   http://phpunit.de/




                                         ginger monkey - popofatticus@flickr - CC attrib 2.0
                                                         gorilla: tancread@flickr - CC by-nc
Future: Classes As “Types”
✓   $content->my->number = 123;

✓   $content->my->string = 'ronald';

✗   $content->my->date = '2005-03-10T12:24:14Z';

?   $content->my->set('date',
                     '2005-03-10T12:24:14Z',
                     XN_Attribute::DATE);
Future: Classes As “Types”
Newer:
✓   $content->my->date = 
          new DateTime('2005-03-10T12:24:14Z');

Older:
✓   $content->my->date = 
          XN_Date('2005-03-10T12:24:14Z');
class XN_Date {
    public $_stamp;
    
    public function __construct($timeOrDateString) {
        if (ctype_digit($timeOrDateString)) {
            $this->_stamp = $timeOrDateString;
        } else {
            $failure = (version_compare(phpversion(),'5.1.0') >= 0) ? -1 : false;
            $stamp = strtotime($timeOrDateString);
            if ($stamp === $failure) {
                throw new Exception("$timeOrDateString is not a valid time/date");
            } else {
                $this->_stamp = $stamp;
            }
        }
    }
    
    public function __get($property) {
        if ($property == 'epoch') {
            return (integer) $this->_stamp;
        } else if ($property == 'ISO8601') {
            return $this->__toString();
        } else {
            return gmdate($property, $this->_stamp);
        }
    }
    
    public function __toString() {
        return gmstrftime('%Y-%m-%dT%H:%M:%SZ',$this->_stamp);
    }
}
function XND_Date($timeOrDateString) { return new XND_Date($timeOrDateString); }
Resources
•   Joshua Bloch: "How to Design a Good API and
    Why It Matters"

    •   http://lcsd05.cs.tamu.edu/slides/keynote.pdf

•   Zend Framework Documentation

    •   http://framework.zend.com/manual/manual/

•   eZ Components Documentation

    •   http://ez.no/doc/components/overview/

•   These slides: http://www.sklar.com/blog/
Come work at                         !

• Write the code that powers 100,000+ social
  networks
• Write the next version of our PHP API
• Work in Palo Alto (or not)
• http://jobs.ning.com - david@ninginc.com

More Related Content

What's hot

PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii
명철 강
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
Hugo Hamon
 
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Cliff Seal
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
Hugo Hamon
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
Hugo Hamon
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8PrinceGuru MS
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
Flavio Poletti
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
Flavio Poletti
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
Kacper Gunia
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
Jace Ju
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
Ross Tuck
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
Ross Tuck
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Masahiro Nagano
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Kris Wallsmith
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of SmartmatchAndrew Shitov
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith
 

What's hot (20)

PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
Advanced php testing in action
Advanced php testing in actionAdvanced php testing in action
Advanced php testing in action
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Command Bus To Awesome Town
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 

Viewers also liked

PRESENTACION DE PRUEBA
PRESENTACION DE PRUEBAPRESENTACION DE PRUEBA
PRESENTACION DE PRUEBAelojoenlanuca
 
Mentoring
MentoringMentoring
洗手間裡的晚宴
洗手間裡的晚宴 洗手間裡的晚宴
洗手間裡的晚宴 Carol Cheung
 
Social Media
Social MediaSocial Media
คู่มือการใช้งาน Wmap 2013
คู่มือการใช้งาน Wmap 2013คู่มือการใช้งาน Wmap 2013
คู่มือการใช้งาน Wmap 2013
Sonoda Kyousuke
 
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job? Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Stanford GSB Corporate Governance Research Initiative
 

Viewers also liked (8)

PRESENTACION DE PRUEBA
PRESENTACION DE PRUEBAPRESENTACION DE PRUEBA
PRESENTACION DE PRUEBA
 
Mentoring
MentoringMentoring
Mentoring
 
洗手間裡的晚宴
洗手間裡的晚宴 洗手間裡的晚宴
洗手間裡的晚宴
 
Zzz
ZzzZzz
Zzz
 
Social Media
Social MediaSocial Media
Social Media
 
คู่มือการใช้งาน Wmap 2013
คู่มือการใช้งาน Wmap 2013คู่มือการใช้งาน Wmap 2013
คู่มือการใช้งาน Wmap 2013
 
Bab 1 4
Bab 1 4Bab 1 4
Bab 1 4
 
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job? Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
 

Similar to Zendcon 2007 Api Design

Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
Michelangelo van Dam
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
Legacy applications - 4Developes konferencja, Piotr Pasich
Legacy applications  - 4Developes konferencja, Piotr PasichLegacy applications  - 4Developes konferencja, Piotr Pasich
Legacy applications - 4Developes konferencja, Piotr PasichPiotr Pasich
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
Yusuke Wada
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
Perforce
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
Michelangelo van Dam
 
Developing cacheable backend applications - Appdevcon 2019
Developing cacheable backend applications - Appdevcon 2019Developing cacheable backend applications - Appdevcon 2019
Developing cacheable backend applications - Appdevcon 2019
Thijs Feryn
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Codemotion
 
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Codemotion
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
Nate Abele
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
Pierre MARTIN
 
HTTP Caching and PHP
HTTP Caching and PHPHTTP Caching and PHP
HTTP Caching and PHP
David de Boer
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking Sebastian Marek
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
Marcus Ramberg
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
Bastian Feder
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 

Similar to Zendcon 2007 Api Design (20)

Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Legacy applications - 4Developes konferencja, Piotr Pasich
Legacy applications  - 4Developes konferencja, Piotr PasichLegacy applications  - 4Developes konferencja, Piotr Pasich
Legacy applications - 4Developes konferencja, Piotr Pasich
 
Blog Hacks 2011
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
 
Workshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfastWorkshop quality assurance for php projects - phpbelfast
Workshop quality assurance for php projects - phpbelfast
 
Developing cacheable backend applications - Appdevcon 2019
Developing cacheable backend applications - Appdevcon 2019Developing cacheable backend applications - Appdevcon 2019
Developing cacheable backend applications - Appdevcon 2019
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
 
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
Thijs Feryn - Leverage HTTP to deliver cacheable websites - Codemotion Berlin...
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
 
HTTP Caching and PHP
HTTP Caching and PHPHTTP Caching and PHP
HTTP Caching and PHP
 
vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking vfsStream - effective filesystem mocking
vfsStream - effective filesystem mocking
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 

Recently uploaded

Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
CatarinaPereira64715
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 

Recently uploaded (20)

Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 

Zendcon 2007 Api Design