SlideShare a Scribd company logo
1 of 83
API Design
   Shawn M Moore
Best Practical Solutions

   http://sartak.org
Google   API
CC-BY-SA Yuval Kogman,
        2006
CC-BY-SA Yuval Kogman,
        2006
CC-BY-SA Hans Dieter
   Pearcey, 2009
Moose
Path::Dispatcher
 HTTP::Engine
    Dist::Zilla
   IM::Engine


  API
CC-BY-SA-NC Will Spaetzel,
         2005
THE SECRET
THE


WRITE
TESTS
WRITE TESTS
WRITEWRITE
TESTSTESTS
WRITEWRITE
TESTSTESTS
DO THIS

WRITE WRITE RITE WRITE WRITE
            W
         WRITE
 WRITE




                       WRI




                       WRITE
            WRI            TE
      WRITE     TE
      WRITE WRIT E     WR ITE
Test!

use base 'Class::Accessor::Fast';
__PACKAGE__->mk_ro_accessors('birthday');



use Moose;
has birthday => (is => 'ro');




                                API
Test!
Test!
Test!
Test!
Moose
package Point;
use Moose;

has x => (
   is => 'ro',
   isa => 'Num',
);



          Moose
Metaobject Protocol


          Class::MOP




 Moose   Class::MOP
Metaobject Protocol

has cache => (
   is => 'ro',
);
Metaobject Protocol

       has cache => (
          is => 'ro',
       );


                    Moose::Meta::Attribute
has Moose::Meta::Attribute
Metaobject Protocol

has cache => (
   is => 'ro',
);



 Moose::Meta::Method::Accessor
 cache
Metaobject Protocol
 class PersistentAttr
 extends Moose::Meta::Attribute {
    …
 }

 has cache => (
    metaclass => 'PersistentAttr',
    is => 'ro',
 );
Moose
Metaobject Protocol
role PersistentAttr {
   …
}

has cache => (
   traits => ['PersistentAttr'],
   is => 'ro',
);
Moose
  X
MooseX   MOP
Sugar Layer



Moose
Sugar Layer

my $class = get_class();
Sugar Layer
my $class = get_class();

$class->has(
   birthday => (
      is => 'ro',
   )
);



   has
Sugar Layer
my $class = get_class();

no strict 'refs';
*{$class.'::has'}->(
   birthday => (
      is => 'ro',
   )
);

                           has
Sugar Layer
my $class = get_class();

no strict 'refs';
*{$class.'::has'}->(
   birthday => (
      is => 'ro',
   )
);
Sugar Layer

Class::MOP::Class
 ->initialize($class)
   ->add_attribute(
    $name, %options);




   has            add_attribute
Sugar Layer
my $class = get_class();

$class->meta->add_attribute(
   birthday => (
      is => 'ro',
   )
);
Sugar Layer
use MooseX::Declare;

class Point3D extends Point {
   has z => (…);

    after clear {
       $self->z(0);
    }
}
Path::Dispatcher
use Path::Dispatcher::Declarative -base;

on ['wield', qr/^w+$/] => sub {
  wield_weapon($2);
}

under display => sub {
   on inventory => sub { show_inventory };
   on score   => sub { show_score };
};

YourDispatcher->run('display score');


                  Jifty::Dispatcher        Prophet
Path::Dispatcher::Declar
use Sub::Exporter -setup => {
   exports => [
      on => &build_on,
      under => &build_under,
      …,
   ],
};



             Sub::Exporter
Path::Dispatcher::Declar
use Sub::Exporter -setup => {
   exports => [
      on => &build_on,
      under => &build_under,
      …,
   ],
};
Path::Dispatcher::Builder
            Robert Krimen
               "grink"



   Robert Krimen
Path::Dispatcher::Builder

return {
   on => sub { $builder->on(@_) },
   under => sub { $builder->under(@_) },
   …,
};
grink++


OO
HTTP::Engine
HTTP::Engine->new(
  interface => {
     module => 'ServerSimple',
     args => { … },
     request_handler => sub {
        …
     },
  },
)->run;


HTTP::Engine
HTTP::Engine
HTTP::Engine->new(
  interface => {
     module => 'ModPerl',
     args => { … },
     request_handler => sub {
        …
     },
  },
)->run;


              mod_perl
HTTP::Engine
HTTP::Engine->new(
  interface => {
     module => 'FCGI',
     args => { … },
     request_handler => sub {
        …
     },
  },
)->run;


                  FastCGI
HTTP::Engine

 request_handler => sub {
   my $request = shift;
   return $response;
 }




HTTP::Engine       IO
HTTP::Engine

request_handler => sub {
  my $request = shift;
  return $response;
}




HTTP::Engine               OK
HTTP::Engine

request_handler => sub {
  my $request = shift;
  return $response;
}
HTTP::Engine++


        1
CC-BY-SA Hans Dieter
   Pearcey, 2009
Dist::Zilla
        AllFiles
    ExtraTests
     InstallDirs
        License
   MakeMaker
       Manifest
  ManifestSkip
    MetaYAML
   PkgVersion
      PodTests
   PodVersion
    PruneCruft
       Readme
UploadToCPAN
Dist::Zilla
         AllFiles
     ExtraTests
      InstallDirs
         License         $_->gather_files
    MakeMaker            for
        Manifest         $self->plugins_with(
   ManifestSkip
                         -FileGatherer
     MetaYAML
    PkgVersion           );
       PodTests
    PodVersion
     PruneCruft
        Readme
 UploadToCPAN

Dist::Zilla
Dist::Zilla
        AllFiles
    ExtraTests
     InstallDirs
        License            $_->gather_files
   MakeMaker               for
       Manifest            $self->plugins_with(
  ManifestSkip
                           -FileGatherer
    MetaYAML
   PkgVersion              );
      PodTests
   PodVersion
    PruneCruft
       Readme
UploadToCPAN

            plugins_with
Dist::Zilla
                   AllFiles
   ExtraTests
   InstallDirs
                   License    $_->gather_files
  MakeMaker                   for
    Manifest                  $self->plugins_with(
 ManifestSkip
                              -FileGatherer
                 MetaYAML
   PkgVersion                 );
                  PodTests
   PodVersion
   PruneCruft
                  Readme
UploadToCPAN
Dist::Zilla
                   AllFiles
   ExtraTests
   InstallDirs
                   License    $_->gather_files
  MakeMaker                   for
    Manifest                  $self->plugins_with(
 ManifestSkip
                              -FileGatherer
                 MetaYAML
  PkgVersion                  );
                  PodTests
  PodVersion
  PruneCruft
                  Readme
UploadToCPAN
         gather_files
Dist::Zilla
        AllFiles
                   ExtraTests
                   InstallDirs
        License               $_->munge_files
    MakeMaker                 for
      Manifest                $self->plugins_with(
   ManifestSkip
                              -FileMunger
     MetaYAML
                   PkgVersion );
      PodTests
                   PodVersion
     PruneCruft
        Readme
 UploadToCPAN

Dist::Zilla
Request Tracker
User/Prefs.html

   $m->callback(
      CallbackName => 'FormEnd',
      UserObj => $UserObj,
      …,
   );



     RT
Request Tracker
User/Prefs.html

   $m->callback(
      CallbackName => 'FormEnd',
      UserObj => $UserObj,
      …,
   );
Request Tracker
User/Prefs.html

   $m->callback(
      CallbackName => 'FormEnd',
      UserObj => $UserObj,
      …,
   );


                   FormEnd
Request Tracker
User/Prefs.html

   $m->callback(
      CallbackName => 'FormEnd',
      UserObj => $UserObj,
      …,
   );
Request Tracker
User/Prefs.html

   $m->callback(
      CallbackName => 'FormEnd',
      UserObj => $UserObj,
      …,
   );
Request Tracker
commit 4c05a6835eef112701ac58dfd1b133e220059d4f
Author: Jesse Vincent <jesse@bestpractical.com>

Date: Fri Dec 27 18:50:06   2002 -0500
  Attempting mason callouts


Ticket/Update.html
     <& /Elements/Callback,
       Name => 'BeforeTextarea',
       %ARGS
     &>
                              7
Dist::Zilla
              Choice
ModuleBuild     or     MakeMaker

MetaYAML        or     MetaJSON
Dist::Zilla
     Extensibility

Dist::Zilla::Plugin::CriticTests


Dist::Zilla::Plugin::Repository


Dist::Zilla::Plugin::PerlTidy
Dist::Zilla
     Extensibility

Dist::Zilla::Plugin::CriticTests
                   InlineFiles
Dist::Zilla::Plugin::Repository
                   MetaProvider
Dist::Zilla::Plugin::PerlTidy
                   FileMunger
Dist::Zilla
     Extensibility

Dist::Zilla::Plugin::BPS::Secret
CC-BY-SA Hans Dieter
   Pearcey, 2009
IM::Engine
incoming_callback => sub {
   my $incoming = shift;

    my $message = $incoming->plaintext;
    $message =~ tr[a-zA-Z][n-za-mN-ZA-M];

    return $incoming->reply($message);
}




                                IM::Engine
IM::Engine

$self->plugin_collect(
  role => 'ExtendsObject::User',
  method => 'traits',
);




                           plugin_collect
IM::Engine

$self->plugin_collect(
  role => 'ExtendsObject::User',
  method => 'traits',
);
IM::Engine

$self->plugin_collect(
  role => 'ExtendsObject::User',
  method => 'traits',
);




         traits
IM::Engine
my @all_traits =
$self->plugin_collect(
  role => 'ExtendsObject::User',
  method => 'traits',
);
method plugin_collect {
  my @items;

    $self->each_plugin(
       callback => sub {
          push @items,
            shift->$method
       },
    );

    return @items;
}
             plugin_collect
IM::Engine
method new_with_plugins {
  my %args = (
     $self->plugin_collect(
        role => …,
        method => 'ctor_args',
     ),
     @_,
  );
  $self->new(%args);
}
IM::Engine

push @{ $args{traits} },
  $self->plugin_collect(
     role => …,
     method => 'traits',
  );

$self->new_with_traits(%args);
MooseX::Traits
 $object = Class->new_with_traits(
    traits => ['Counter'],
 );

 $other = Class->new;

 $object->counter; # 0
 $other->counter; # Can't locate...

new_with_traits   MooseX::Traits
MooseX::Traits
$object = Class->new_with_traits(
   traits => ['Counter'],
);

$other = Class->new;

$object->counter; # 0
$other->counter; # Can't locate...
Role = Trait


Moose      Role   Trait
Moose
Path::Dispatcher
 HTTP::Engine
    Dist::Zilla
   IM::Engine
Moose
             Extensibility
          Separation of sugar

         Dist::Zilla
        IM::Engine

Moose
Moose
     Path::Dispatcher
           OO sugar layer
        Dist::Zilla
       IM::Engine

OO
Moose
Path::Dispatcher
 HTTP::Engine
  Omit inconsequential details

   IM::Engine
Moose
Path::Dispatcher
 HTTP::Engine
   Dist::Zilla
     Explicit pluggability
Moose
             Path::Dispatcher
              HTTP::Engine
                 Dist::Zilla
                IM::Engine
                 Extreme pluggability
                        DRY
IM::Engine                     DRY
WRITEMoose
 Path::Dispatcher
  HTTP::Engine

TESTS!!!
     Dist::Zilla
    IM::Engine
Moose
Path::Dispatcher
 HTTP::Engine
    Dist::Zilla
   IM::Engine
Thanks to my



Kenichi Ishigaki



       83

More Related Content

What's hot

Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Fabien Potencier
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128PrinceGuru MS
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Fabien Potencier
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2Hugo Hamon
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010Fabien Potencier
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)Fabien Potencier
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Developmentjsmith92
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Kris Wallsmith
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Symfony without the framework
Symfony without the frameworkSymfony without the framework
Symfony without the frameworkGOG.com dev team
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
Dependency Injection in PHP
Dependency Injection in PHPDependency Injection in PHP
Dependency Injection in PHPKacper Gunia
 

What's hot (20)

Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Symfony without the framework
Symfony without the frameworkSymfony without the framework
Symfony without the framework
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Dependency Injection in PHP
Dependency Injection in PHPDependency Injection in PHP
Dependency Injection in PHP
 
CodeIgniter 3.0
CodeIgniter 3.0CodeIgniter 3.0
CodeIgniter 3.0
 

Viewers also liked

Analysis on the strawberry pink villa - vocabulary
Analysis on the strawberry pink villa  - vocabularyAnalysis on the strawberry pink villa  - vocabulary
Analysis on the strawberry pink villa - vocabularyLuna
 
Healthcare2.0 Turning Hell care into healthcare
Healthcare2.0 Turning Hell care into healthcareHealthcare2.0 Turning Hell care into healthcare
Healthcare2.0 Turning Hell care into healthcareBetsy Bevilacqua
 

Viewers also liked (6)

My Health Place
My Health Place My Health Place
My Health Place
 
ASB Web2workshop
ASB Web2workshopASB Web2workshop
ASB Web2workshop
 
Calendar 2009
Calendar 2009Calendar 2009
Calendar 2009
 
NCCE workshop11
NCCE workshop11NCCE workshop11
NCCE workshop11
 
Analysis on the strawberry pink villa - vocabulary
Analysis on the strawberry pink villa  - vocabularyAnalysis on the strawberry pink villa  - vocabulary
Analysis on the strawberry pink villa - vocabulary
 
Healthcare2.0 Turning Hell care into healthcare
Healthcare2.0 Turning Hell care into healthcareHealthcare2.0 Turning Hell care into healthcare
Healthcare2.0 Turning Hell care into healthcare
 

Similar to Api Design

Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Perl web app 테스트전략
Perl web app 테스트전략Perl web app 테스트전략
Perl web app 테스트전략Jeen Lee
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Curscatalyst
CurscatalystCurscatalyst
CurscatalystKar Juan
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hopeMarcus Ramberg
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012D
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowVrann Tulika
 
CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)brian d foy
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Jakub Zalas
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)andrewnacin
 
Getting Started with Capistrano
Getting Started with CapistranoGetting Started with Capistrano
Getting Started with CapistranoLaunchAny
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 

Similar to Api Design (20)

Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Perl web app 테스트전략
Perl web app 테스트전략Perl web app 테스트전략
Perl web app 테스트전략
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Curscatalyst
CurscatalystCurscatalyst
Curscatalyst
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Hacking Movable Type
Hacking Movable TypeHacking Movable Type
Hacking Movable Type
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hope
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
 
CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
Getting Started with Capistrano
Getting Started with CapistranoGetting Started with Capistrano
Getting Started with Capistrano
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 

Recently uploaded

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
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
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
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
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
 
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
 
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
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
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
 
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
 
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
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 

Recently uploaded (20)

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
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
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
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
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
 
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...
 
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
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
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
 
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
 
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
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 

Api Design

Editor's Notes

  1. Presented YAPC::Asia, 2009-09-10. Tokyo Institute of Technology, Tokyo, Japan.
  2. There is a good Google Tech Talk on &quot;how to design an API and why it matters&quot;. There isn&apos;t a whole lot of overlap between this talk and that one. Watch that one. http://www.youtube.com/watch?v=aAb7hSCtvGw
  3. At YAPC::NA 2009, this guy, Hans Dieter Pearcey aka confound aka hdp, presented a talk about Dist::Zilla. http://www.flickr.com/photos/nuffin/179250512/
  4. Dist::Zilla was written by this other guy, Ricardo Signes, aka rjbs. http://www.flickr.com/photos/nuffin/179250812/
  5. Dieter presented this slide about Dist::Zilla&apos;s pluggable design. I loved it and I wanted to devote an entire talk to its glory. http://weftsoar.net/~hdp/dzil/
  6. I&apos;m here to highlight really cool API designs that these projects have. In particular, they design for extensibility and pluggability. Extensibility is really important to the current and future success of these projects.
  7. If you haven&apos;t noticed yet, this talk is going to be very Moose-heavy. All those modules have the Moose nature. http://www.flickr.com/photos/redune/6562798/
  8. There is a poorly kept secret for designing great APIs. I hope that all of you already do this, but you probably do not do it enough.
  9. Write tests.
  10. Write so many tests your ears bleed. I am not joking!
  11. If you remember nothing else, remember to write tests!
  12. Write tests so you can tell if your API is painful to use. Which of these would you rather be stuck with? Make it painless for your users. Some of them might be using your module a lot. If it&apos;s tedious to use your module...
  13. ... then you&apos;ll piss your users off. They&apos;ll leave and use some other module, or worse, find out where you live.
  14. This is Jesse Vincent, the nicest guy in the world :)
  15. Moose serves as the foundation for the rest of the talk, so I want to explain what it &quot;got right&quot; in terms of its API. These next few slides are difficult but it will get clearer and less heady, so wake up soon if you space out.
  16. Moose is built on top of a metaobject protocol. This is Class::MOP. See my &quot;Extending Moose for Applications&quot; talk for a proper introduction to the metaobject protocol http://sartak.org/talks/yapc-na-2009/extending-moose/
  17. The MOP is vital to Moose&apos;s operation. Basically, it means that every part of your class is represented by an object.
  18. When you say &quot;has&quot; it creates an instance of the Moose::Meta::Attribute class, which holds information like the attribute&apos;s name, its type constraint, default value, etc.
  19. The is =&gt; &apos;ro&apos; option creates a &quot;cache&quot; method in your class. It also creates an object of class Moose::Meta::Method::Accessor to represent that &quot;cache&quot; method.
  20. This is important because we can subclass Moose&apos;s class to add our own special logic, such as making the cache persist across processes. Subclassing and adding logic is ordinary object-oriented programming!
  21. We can also specify roles to apply to cache&apos;s attribute object. This is slightly better because it means a single attribute can have many extensions. Just like how it&apos;s better to design with roles than subclasses in ordinary programming.
  22. The metaobject protocol powers most of the MooseX modules. In my opinion, the metaobject protocol is responsible for a very large part of Moose&apos;s popularity. The other reason for Moose&apos;s popularity is it enables concise class code.
  23. Moose also makes a very clean separation between its sugar layer and the rest of the system.
  24. Say you wanted to get ahold of some class...
  25. Then add an attribute to it. This doesn&apos;t work because &quot;has&quot; is not a method. Its first parameter is supposed to be the attribute name, not the class you&apos;re adding the attribute to.
  26. So we have to call $class&apos;s &quot;has&quot; as a function. This kind of thing is ridiculous. Maybe the other class has used &quot;no Moose&quot; so that &quot;has&quot; is deleted. Or perhaps it renamed &quot;has&quot;.
  27. Not to mention how ugly this mess is.
  28. If we look at the source code of Moose, we can see &quot;has&quot; is basically a wrapper around the &quot;add_attribute&quot; method of the Class::MOP::Class instance.
  29. Much better. There&apos;s no messy syntax. This can be used outside of $class&apos;s namespace just fine. This also works if class has cleaned up after Moose with &quot;no Moose&quot; or namespace::clean.
  30. Having a clean sugar layer means that other people can write better sugar. I like the idea of providing a separate Devel::Declare-powered sugar layer in a separate distribution. It forces you to cleanly separate the pieces.
  31. Path::Dispatcher is a standalone-URI dispatcher. I wrote it because I wanted Jifty::Dispatcher for Prophet&apos;s command-line interface. This is its sugar layer. Like Moose, it has a clean, extensible API if you want the freedom to do unusual things.
  32. It used to be that Path::Dispatcher::Declarative was implemented as an ordinary Sub::Exporter-using module.
  33. This is not at all extensible. You can&apos;t change the meaning of &quot;on&quot; or &quot;under&quot; because these are hardcoded. Reusing this sugar would be painful as well.
  34. This was fine for a few weeks, but then Robert Krimen started using Path::Dispatcher. And he wanted to extend it for a module he was writing called Getopt::Chain.
  35. Path::Dispatcher::Builder makes the sugar layer creation use OOP. This let Robert subclass Path::Dispatcher::Builder and use it for his own modules. He can reuse the regular dispatcher logic, tweak it by overriding methods, and add his own behavior.
  36. OO sugar is a really neat idea that I haven&apos;t seen anywhere else.
  37. HTTP::Engine abstracts away the various HTTP server interfaces that Perl has accumulated since HTTP was invented. The benefit is in letting the user pick which server interface best fits their particular needs.
  38. For example, you can use mod_perl if you enjoy pain.
  39. Or FastCGI if you&apos;re a cool dude.
  40. HTTP::Engine works well because the code you write doesn&apos;t have to worry about redirecting I/O streams, making sense of %ENV, or any of the other crap you do when writing against a particular server module.
  41. HTTP::Engine boils the web server cycle to the least common denominator. You take a request...
  42. &amp;#x2026; and return a response.
  43. Can we please standardize on this? New server modules can implement an HTTP::Engine::Interface, then immediately every existing HTTP::Engine-based application can switch to it by changing only a single line of code.
  44. Now I want to explain why this is so awesome.
  45. Here&apos;s a list of plugins used by a typical Dist::Zilla-based distribution.
  46. Dist::Zilla itself occasionally calls methods like this. The key bit is &quot;plugins_with&quot;.
  47. plugins_with takes a role name...
  48. ...and selects the plugins that &quot;do&quot; the role. These plugins all do the &quot;FileGatherer&quot; role, which means the plugin adds files to a distribution.
  49. Then, dzil calls gather_files on each of these plugins so it can actually add files to the distribution. &quot;License&quot;, &quot;Readme&quot;, and &quot;MetaYAML&quot; add the respective files, &quot;AllFiles&quot; adds every file the author wrote. &quot;PodTests&quot; adds pod testing files to the distribution.
  50. Dist::Zilla uses this architecture for all of the interesting parts of building a CPAN distribution. This is &quot;munging files&quot;, which lets plugins edit files to increase the version number, or move tests around.
  51. It turns out that RT has a very similar extension mechanism.
  52. This code exists in User/Prefs.html. The callback method selects all plugins that do the &quot;User/Prefs.html&quot; &quot;role&quot;.
  53. Then it calls the FormEnd &quot;method&quot; (template) on these selected plugins.
  54. And you can pass arbitrary parameters to each method.
  55. This works extremely well for us! We try to build most customer extensions with callbacks. It&apos;s basically the same design as Dist::Zilla&apos;s.
  56. RT has had callbacks since 2002, first released in 3.0.0. This pattern has been the best mechanism for any kind of RT extension for almost seven years now.
  57. This design gives the user choice over which behavior she wants. And in my experience, users really really want choice.
  58. This design is also extensible for free. These are some of the modules that have been written to extend Dist::Zilla.
  59. All they need to do is fulfill the requirements of the roles they &quot;do&quot;. I&apos;m going to talk about that more in my (Parameterized) Roles talk. http://sartak.org/talks/yapc-asia-2009/(parameterized)-roles/
  60. Extensibility is also important for code you can&apos;t share. We can&apos;t ask Ricardo to include company secrets for Dist::Zilla, and maintaining a fork really sucks.
  61. So now you know!
  62. IM::Engine is a project I&apos;m working on. It&apos;s basically HTTP::Engine for IM. You can write a bot, once, that will run on any service IM::Engine can talk to, including IRC. IM::Engine smooths over the differences in the protocols.
  63. I&apos;ve extended Ricardo&apos;s design with a number of helper methods. plugin_collect is the one I like best.
  64. For each plugin that does the ExtendsObject::User role...
  65. ...call its &quot;traits&quot; method.
  66. The return value of this call is the list of all return values of the &quot;traits&quot; methods.
  67. This is the important part of plugin_collect&apos;s implementation. There&apos;s not much there. I like very layered APIs because they&apos;re easier to understand and reuse, especially by your users, than huge monolithic methods. Each layer does only a little bit of work.
  68. Here&apos;s a piece of design I like a lot. This lets plugins participate in object construction. Each plugin can provide constructor arguments.
  69. This lets plugins participate even more in object construction. Now plugins can provide roles for the object you&apos;re constructing. This lets plugins add attributes and methods to the object. I use this in a plugin to give state management methods to User objects.
  70. new_with_traits comes from MooseX::Traits. It&apos;s a really nice module for designing pluggable and extensible systems. You just pass a list of roles to new_with_traits and it will arrange it so that the object does those roles.
  71. Other objects of that class are not affected by new_with_traits. The way it works internally is by creating a new subclass of Class. This is vital because it maintains modularity. I don&apos;t want my extensions to screw up your extensions.
  72. In Moose land, roles and traits are basically synonymous. Some people will tell you there are subtle differences, but there&apos;s no clear consensus. I just say &quot;roles&quot; except when I have to say &quot;traits&quot; for a module.
  73. So that is all I have time to cover. There are plenty more nice examples in modules like KiokuDB, Fey, and the now-moosified Catalyst.
  74. Moose teaches us that extensibility can lead to a great corpus of extensions. Separation of sugar keeps you and your users flexible.
  75. The OO sugar layer is a new idea that I hope catches on. I&apos;ll have to dedicate more time to it.
  76. If you omit inconsequential details, then your application remains flexible and concise.
  77. Pluggability does not have to be implicit, as in subclassing. Explicitly controlling pluggability lets you do more interesting things.
  78. &amp;#x2026; such as the things IM::Engine does, by letting plugins manipulate system objects. It also provides methods for common plugin operations so you don&apos;t have to repeat them everywhere.
  79. I almost forgot...
  80. I almost forgot...
  81. Thank you to Ishigaki-san for translating my slides!