+ All Categories

Psr-7

Date post: 19-Jul-2015
Category:
Upload: marco-perone
View: 173 times
Download: 0 times
Share this document with a friend
Popular Tags:
38
PSR-7 A SET OF COMMON INTERFACES FOR HTTP MESSAGES by Marco Perone / @marcoshuttle
Transcript
Page 1: Psr-7

PSR-7A SET OF COMMON INTERFACES FOR HTTP

MESSAGESby Marco Perone / @marcoshuttle

Page 2: Psr-7

HTTP MESSAGES

Page 3: Psr-7

HTTP MESSAGE STRUCTURE <message line> Header: value Another­Header: value

Message body

Page 4: Psr-7

BODYstringhandled by server and clients as a streamPHP natively represents it using streams

Page 5: Psr-7

REQUEST MESSAGE LINE

METHOD REQUEST-TARGET HTTP/VERSION

Page 6: Psr-7

REQUEST TARGETorigin formabsolute formauthority formasterisk form

Page 7: Psr-7

URI

SCHEME://AUTHORITY[/PATH][?QUERYSTRING]

AUTHORITY = [USER[:PASS]@]HOST[:PORT]

Page 8: Psr-7

RESPONSE MESSAGE LINE

HTTP/VERSION STATUS REASON

Page 9: Psr-7

USE OF HTTP MESSAGES IN PHP

Page 10: Psr-7

USE CASE 1USE PHP SUPERGLOBALS

Any application before frameworks

Page 11: Psr-7

USE CASE 2CREATE NEW IMPLEMENTATION FROM

SCRATCHFrameworks define http components

Single purpose libraries (oauth-server-php)Http clients ad Guzzle and Buzz

Page 12: Psr-7

USE CASE 3REQUIRE A SPECIFIC HTTP CLIENT/SERVER

LIBRARY PROVIDING MESSAGEIMPLEMENTATION

Silex, Stack, Drupal 8 have hard dependencies on Symfony'sHTTP kernel

Any SDK developed with Guzzle has a hard requirement onGuzzle's HTTP message implementations

Page 13: Psr-7

USE CASE 4CREATE ADAPTERS FOR COMMON HTTP

MESSAGE IMPLEMENTATIONSProjects such as Geocoder create redundant adapters for

common libraries

Page 14: Psr-7

PROBLEMSSuperglobals are mutable. Libraries can alter state of theapplicationUnit and integration testing difficultProjects not capable of interoperability or cross-pollinationNecessity of building a bridge layer between applicationsAny content emitted before a call to header() will resultin that a call becoming a no-op

Page 15: Psr-7

THE SCOPE OF PSR-7

Page 16: Psr-7

GOALSProvide the interfaces needed for describing HTTPmessagesFocus on practical applications and usabilityDefine the interfaces to model all elements of the HTTPmessage and URI specificationsEnsure that the API does not impose arbitrary limits onHTTP messagesProvide useful abstractions both for handling incomingrequests for server-side applications and for sendingoutgoing requests in HTTP clients

Page 17: Psr-7

NON GOALSDoes not expect all HTTP client libraries or server-sideframeworks to change their interfaces to conform. It isstrictly meant for interoperabilityShould not impose implementation details

Page 18: Psr-7

USE CASES

Page 19: Psr-7

CLIENTSUnified message interface to use for making requests

$response = $client­>send($request);

Page 20: Psr-7

MIDDLEWARESFunction that accepts request and response as parametersand does something with them, including delegating to the

next middleware

function ( ServerRequestInterface $request, ResponseInterface $response, callable $next = null) # do stuff here

Page 21: Psr-7

FRAMEWORKSThey did HTTP message abstraction since a long time

PSR-7 provides a common set of interfaces

Consider Zend\Stdlib\DispatchableInterface inZend Framework 2

use Zend\Http\RequestInterface;use Zend\Http\ResponseInterface;

interface DispatchableInterface public function dispatch( RequestInterface $request, ResponseInterface $response );

Page 22: Psr-7

PSR-7 BY EXAMPLES

Page 23: Psr-7

INTERMEZZO: VALUE OBJECTSMessages and URIs are modeled as value objects

a change to any aspect of the message is essentially a newmessageimmutabilityensure integrity of message stateuse a base instance as prototype

Page 24: Psr-7

MESSAGESnamespace Psr\Http\Message;

MessageInterfaceResponseInterfaceRequestInterfaceServerRequestInterface

Page 25: Psr-7

HEADERS

// Returns null if not found:$header = $message­>getHeader('Accept');

// Test for a header:if (! $message­>hasHeader('Accept'))

// If the header has multiple values, fetch them// as an array:$values = $message­>getHeaderLines('X­Foo');

Page 26: Psr-7

HEADERS

/* Returns the following structure: [ 'Header' => [ 'value1' 'value2' ] ]*/foreach ($message­>getAllHeaders() as $header => $values)

Page 27: Psr-7

HEADERS

$new = $message­>withHeader('Location', 'http://example.com');

$message = $message­>withHeader('Location', 'http://example.com');

$message = $message­>withAddedHeader('X­Foo', 'bar');

$message = $message­>withoutHeader('X­Foo');

Page 28: Psr-7

BODIEStreated as streams

StreamableInterface is used

$body = new Stream('php://temp');$body­>write('Here is the content for my message!');

$message = $message­>withBody(new Stream('php://temp'));

Page 29: Psr-7

RESPONSESstatus codereason phrase

$status = $response­>getStatusCode();$reason = $response­>getReasonPhrase();

$response = $response­>withStatus(418, "I'm a teapot");

Page 30: Psr-7

REQUESTSmethodrequest target

Page 31: Psr-7

REQUEST TARGET AND URIThe request interface:

composes a UriInterface instance, which models theURI itselfprovides two methods around request-targets:getRequestTarget() andwithRequestTarget()

Page 32: Psr-7

URI INTERFACEURI are treated as value objects

// URI parts: $scheme = $uri­>getScheme(); $userInfo = $uri­>getUserInfo(); $host = $uri­>getHost(); $port = $uri­>getPort(); $path = $uri­>getPath(); $query = $uri­>getQuery(); // the query STRING $authority = $uri­>getAuthority(); // [user­info@]host[:port]

$uri = $uri ­>withScheme('http') ­>withHost('example.com') ­>withPath('/foo/bar') ­>withQuery('?baz=bat');

Page 33: Psr-7

CREATE REQUEST

$request = $request ­>withMethod('OPTION') ­>withUri($uri­>withPath('/api/user')) ­>withRequestTarget('*');

Page 34: Psr-7

SERVER SIDE REQUESTSPHP's Server API does a number of things for us:

Deserialization of query string arguments ($_GET)Deserialization of urlencoded form data submitted viaPOST ($_POST)Deserialization of cookies ($_COOKIE)Identification and handling of file uploads ($_FILES)Encapsulation of CGI/SAPI parameters ($_SERVER)

Page 35: Psr-7

SERVER SIDE REQUESTSServerRequestInterface extends the base

RequestInterface and offers features around thesevalues

$query = $request­>getQueryParams();$body = $request­>getParsedBody();$cookies = $request­>getCookieParams();$files = $request­>getFileParams();$server = $request­>getServerParams();

Page 36: Psr-7

ATTRIBUTES

$request­>getAttribute($name, $default = null);$request­>getAttributes();$request = $request­>withAttribute($name, $value);$request = $request­>withoutAttribute();

Page 37: Psr-7

REFERENCES


Recommended