Middleware web APIs in PHP 7.x

Post on 22-Jan-2018

84 views 1 download

transcript

MIDDLEWAREWEBAPISINPHP7.XJanBurkl

SolutionConsultingManager

,Dresden,22ndSeptember2017

RogueWaveSoftware

phpdeveloperday2017

PHPPHP:HypertextPreprocessorThemostpopularserver-sidelanguage:PHPisusedby82.6%ofallthewebsites(source:

)UsedbyFacebook,Wikipedia,Yahoo,Etsy,Flickr,Digg,etc22yearsofusage,since1995FullOOPsupportsincePHP5

w3techs.com

PHP7Released:3December2015

Previousmajorwas ,13July2004

SkippedPHP6:Unicodefailure

Lastreleaseis (3Aug2017)

PHP5

7.1.8

PHP7PERFORMANCE

PHP7isalsofasterthan !Python3

BENCHMARK

PHP5.6 PHP7

MemoryUsage 428MB 33MB

Executiontime 0.49sec 0.06sec

$a=[];for($i=0;$i<1000000;$i++){$a[$i]=["hello"];}echomemory_get_usage(true);

MOVINGTOPHP7BadoosavedonemilliondollarsswitchingtoPHP7( )TumblrreducedthelatencyandCPUloadbyhalfmovingtoPHP7( )DailymotionhandlestwicemoretrafficwithsameinfrastructureswitchingtoPHP7( )

source

source

source

PHP7ISNOTONLYFAST!ReturnandScalarTypeDeclarationsImprovedExceptionhierarchyManyfatalerrorsconvertedtoExceptionsSecurerandomnumbergeneratorAuthenticatedencryptionAEAD(PHP7.1+)Nullabletypes(PHP7.1+)and !more

WEBAPISINPHP7

HTTPIN/OUT

EXAMPLERequest:

Response:

GET/api/version

HTTP/1.1200OKConnection:closeContent-Length:17Content-Type:application/json

{"version":"1.0"}

MIDDLEWAREAfunctionthatgetsarequestandgeneratesa

response

usePsr\Http\Message\ServerRequestInterfaceasRequest;useInterop\Http\ServerMiddleware\DelegateInterface;

function(Request$request,DelegateInterface$next){//doingsomethingwith$request...//forinstancecallingthedelegatemiddleware$next$response=$next->process($request);//manipulatethe$responsereturn$response;}

DELEGATEINTERFACE

DelegateInterfaceispartof HTTPMiddlewareproposal

namespaceInterop\Http\ServerMiddleware;

usePsr\Http\Message\ResponseInterface;usePsr\Http\Message\ServerRequestInterface;

interfaceDelegateInterface{/***@returnResponseInterface;*/publicfunctionprocess(ServerRequestInterface$request);}

PSR-15

EXPRESSIVE2.0ThePHPframeworkforMiddlewareapplications

PSR-7HTTPMessagesupport(using)

Supportoflambdamiddleware(PSR-15)anddoublepass($request,$response,$next)Pipingworkflow(using )Features:routing,dependencyinjection,templating,errorhandlingLastrelease2.0.3,28thMarch2017

zend-diactoros

zend-stratigility

INSTALLATIONYoucaninstallExpressive2.0using :

Choosethedefaultoptionsduringtheinstallation

composer

composercreate-project\zendframework/zend-expressive-skeletonapi

DEFAULTTheskeletonhas2URLasexample:/and

/api/ping

Theroutesareregisteredin/config/routes.php

Themiddlewareactionsarestoredin/src/App/Action

ROUTES

/config/routes.php

$app->get('/',App\Action\HomePageAction::class,'home');$app->get('/api/ping',App\Action\PingAction::class,'api.ping');

APIMIDDLEWARE

/src/App/Action/PingAction.php

namespaceApp\Action;

useInterop\Http\ServerMiddleware\DelegateInterface;useInterop\Http\ServerMiddleware\MiddlewareInterface;useZend\Diactoros\Response\JsonResponse;usePsr\Http\Message\ServerRequestInterface;

classPingActionimplementsMiddlewareInterface{publicfunctionprocess(ServerRequestInterface$request,DelegateInterface$delegate){returnnewJsonResponse(['ack'=>time()]);}}

PIPELINEWORKFLOW

/config/pipeline.php

$app->pipe(ErrorHandler::class);$app->pipe(ServerUrlMiddleware::class);

$app->pipeRoutingMiddleware();

$app->pipe(ImplicitHeadMiddleware::class);$app->pipe(ImplicitOptionsMiddleware::class);$app->pipe(UrlHelperMiddleware::class);

$app->pipeDispatchMiddleware();$app->pipe(NotFoundHandler::class);

SERVICECONTAINER

/config/container.php

useZend\ServiceManager\Config;useZend\ServiceManager\ServiceManager;

$config=require__DIR__.'/config.php';$container=newServiceManager();$config=newConfig($config['dependencies']);$config->configureServiceManager($container);$container->setService('config',$config);

return$container;

THEEXPRESSIVEAPP

/public/index.php

chdir(dirname(__DIR__));require'vendor/autoload.php';

call_user_func(function(){$container=require'config/container.php';$app=$container->get(\Zend\Expressive\Application::class);

require'config/pipeline.php';require'config/routes.php';

$app->run();});

ROUTEARESTAPI$app->route('/api/users[/{user-id}]',[Authentication\AuthenticationMiddleware::class,Authorization\AuthorizationMiddleware::class,Api\Action\UserAction::class],['GET','POST','PATCH','DELETE'],'api.users');

//orrouteeachHTTPmethod$app->get('/api/users[/{user-id}]',...,'api.users.get');$app->post('/api/users',...,'api.users.post');$app->patch('/api/users/{user-id}',...,'api.users.patch');$app->delete('/api/users/{user-id}',...,'api.users.delete');

RESTDISPATCHTRAITusePsr\Http\Message\ServerRequestInterface;useInterop\Http\ServerMiddleware\DelegateInterface;

traitRestDispatchTrait{publicfunctionprocess(ServerRequestInterface$request,DelegateInterface$delegate){$method=strtolower($request->getMethod());if(method_exists($this,$method)){return$this->$method($request);}return$response->withStatus(501);//Methodnotimplemented}}

RESTMIDDLEWARE

Api\Action\UserAction.php

classUserActionimplementsMiddlewareInterface{useRestDispatchTrait;

publicfunctionget(ServerRequestInterface$request){$id=$request->getAttribute('user-id',false);$data=(false===$id)?/*allusers*/:/*userid*/;returnnewJsonResponse($data);}

publicfunctionpost(ServerRequestInterface$request){...}publicfunctionpatch(ServerRequestInterface$request){...}publicfunctiondelete(ServerRequestInterface$request){...}}

DANKESCHÖNSlides:http://5square.github.io/talks/

Moreinfo:

Contactme:jan.burkl[at]roguewave.com

Followme:

Credits:

Thisworkislicensedundera.

Iused tomakethispresentation.

https://framework.zend.com/blog

@janatzend

@ezimuel

CreativeCommonsAttribution-ShareAlike3.0UnportedLicensereveal.js