SlideShare ist ein Scribd-Unternehmen logo
1 von 72
Downloaden Sie, um offline zu lesen
REST in practice
with Symfony2
@dlondero
OFTEN...
Richardson Maturity Model
NOT
TALKING
ABOUT...
Level 0

POX - RPC
Level 1

RESOURCES
Level 2

HTTP VERBS
Level 3

HYPERMEDIA
TALKING
ABOUT HOW
TO DO
WHAT WE NEED	

!

•symfony/framework-standard-edition	

!

•friendsofsymfony/rest-bundle	

!

•jms/serializer-bundle	

!

•nelmio/api-doc-bundle
//src/Acme/ApiBundle/Entity/Product.php;!

!

use SymfonyComponentValidatorConstraints as Assert;!
use DoctrineORMMapping as ORM;!

!

/**!
* @ORMEntity!
* @ORMTable(name="product")!
*/!
class Product!
{!
/**!
* @ORMColumn(type="integer")!
* @ORMId!
* @ORMGeneratedValue(strategy="AUTO")!
*/!
protected $id;!

!

!

!

/**!
* @ORMColumn(type="string", length=100)!
* @AssertNotBlank()!
*/!
protected $name;!
/**!
* @ORMColumn(type="decimal", scale=2)!
*/!
protected $price;!
/**!
* @ORMColumn(type="text")!
*/!
protected $description;!
CRUD
Create	

HTTP POST
Request
POST /products HTTP/1.1!
Host: acme.com!
Content-Type: application/json!
!

{!
"name": "Product #1",!
"price": 19.90,!
"description": "Awesome product"!
}!
Response
HTTP/1.1 201 Created!
Location: http://acme.com/products/1!
Content-Type: application/json!
!

{!
"product": {!
"id": 1,!
"name": "Product #1",!
"price": 19.9,!
"description": "Awesome product"!
}!
//src/Acme/ApiBundle/Resources/config/routing.yml!
!
acme_api_product_post:!
pattern: /products!
defaults: { _controller: AcmeApiBundle:ApiProduct:post,
_format: json }!
requirements:!
_method: POST
//src/Acme/ApiBundle/Controller/ApiProductController.php!

!

use FOSRestBundleViewView;!

!

public function postAction(Request $request)!
{!
$product = $this->deserialize(!
'AcmeApiBundleEntityProduct',!
$request!
);!

!
!
!

!
!

if ($product instanceof Product === false) {!
return View::create(array('errors' => $product), 400);!
}!
$em = $this->getEM();!
$em->persist($product);!
$em->flush();!
$url = $this->generateUrl(!
'acme_api_product_get_single',!
array('id' => $product->getId()),!
true!
);!
$response = new Response();!
$response->setStatusCode(201);!
$response->headers->set('Location', $url);!
return $response;!

}
Read	

HTTP GET
Request
GET /products/1 HTTP/1.1!
Host: acme.com
Response
HTTP/1.1 200 OK!
Content-Type: application/json!
!

{!
"product": {!
"id": 1,!
"name": "Product #1",!
"price": 19.9,!
"description": "Awesome product"!
}!
public function getSingleAction(Product $product)!
{!
return array('product' => $product);!
}
Update	

HTTP PUT
Request
PUT /products/1 HTTP/1.1!
Host: acme.com!
Content-Type: application/json!
!

{!
"name": "Product #1",!
"price": 29.90,!
"description": "Awesome product"!
}!
Response
HTTP/1.1 204 No Content!
!

HTTP/1.1 200 OK!
Content-Type: application/json!
!

{!
"product": {!
"id": 1,!
"name": "Product #1",!
"price": 29.90,!
"description": "Awesome product"!
}!
//src/Acme/ApiBundle/Controller/ApiProductController.php!

!
use FOSRestBundleControllerAnnotationsView as RestView;!

!
/**!
* @RestView(statusCode=204)!
*/!
public function putAction(Product $product, Request $request)!
{!
$newProduct = $this->deserialize(!
'AcmeApiBundleEntityProduct',!
$request!
);!

!
if ($newProduct instanceof Product === false) {!
return View::create(array('errors' => $newProduct), 400);!
}!

!
$product->merge($newProduct);!

!
$this->getEM()->flush();!
}
Partial Update	

HTTP PATCH
Request
PATCH /products/1 HTTP/1.1!
Host: acme.com!
Content-Type: application/json!
!

{!
"price": 39.90,!
}!
Response
HTTP/1.1 204 No Content!
!

HTTP/1.1 200 OK!
Content-Type: application/json!
!

{!
"product": {!
"id": 1,!
"name": "Product #1",!
"price": 39.90,!
"description": "Awesome product"!
}!
//src/Acme/ApiBundle/Controller/ApiProductController.php!

!
use FOSRestBundleControllerAnnotationsView as RestView;!

!
/**!
* @RestView(statusCode=204)!
*/!
public function patchAction(Product $product, Request $request)!
{!
$validator = $this->get('validator');!

!
$raw = json_decode($request->getContent(), true);!

!
$product->patch($raw);!

!
if (count($errors = $validator->validate($product))) {!
return $errors;!
}!

!
$this->getEM()->flush();!
}
Delete	

HTTP DELETE
Request
DELETE /products/1 HTTP/1.1!
Host: acme.com
Response

HTTP/1.1 204 No Content
//src/Acme/ApiBundle/Controller/ApiProductController.php!

!
use FOSRestBundleControllerAnnotationsView as RestView;!

!
/**!
* @RestView(statusCode=204)!
*/!
public function deleteAction(Product $product)!
{!
$em = $this->getEM();!
$em->remove($product);!
$em->flush();!
}
Serialization
use JMSSerializerAnnotation as Serializer;!

!

/**!
* @SerializerExclusionPolicy("all")!
*/!
class Product!
{!
/**!
* @SerializerExpose!
* @SerializerType("integer")!
*/!
protected $id;!

!

!

!

/**!
* @SerializerExpose!
* @SerializerType("string")!
*/!
protected $name;!
/**!
* @SerializerExpose!
* @SerializerType("double")!
*/!
protected $price;!
/**!
* @SerializerExpose!
* @SerializerType("string")!
*/!
protected $description;!
Deserialization
//src/Acme/ApiBundle/Controller/ApiController.php!

!
protected function deserialize($class, Request $request, $format = 'json')!
{!
$serializer = $this->get('serializer');!
$validator = $this->get('validator');!

!
try {!
$entity = $serializer->deserialize(!
$request->getContent(),!
$class,!
$format!
);!
} catch (RuntimeException $e) {!
throw new HttpException(400, $e->getMessage());!
}!

!
if (count($errors = $validator->validate($entity))) {!
return $errors;!
}!

!
return $entity;!
}!
Testing
//src/Acme/ApiBundle/Tests/Controller/ApiProductControllerTest.php!

!

use LiipFunctionalTestBundleTestWebTestCase;!

!

class ApiProductControllerTest extends WebTestCase!
{!
public function testPost()!
{!
$this->loadFixtures(array());!

!

$product = array(!
'name' => 'Product #1',!
'price' => 19.90,!
'description' => 'Awesome product',!
);!

!

$client = static::createClient();!
$client->request(!
'POST', !
'/products', !
array(), array(), array(), !
json_encode($product)!
);!

!

$this->assertEquals(201, $client->getResponse()->getStatusCode());!
$this->assertTrue($client->getResponse()->headers->has('Location'));!
$this->assertContains(!
"/products/1", !
$client->getResponse()->headers->get('Location')!
);!
}!
//src/Acme/ApiBundle/Tests/Controller/ApiProductControllerTest.php!

!
public function testPostValidation()!
{!
$this->loadFixtures(array());!

!
$product = array(!
'name' => '',!
'price' => 19.90,!
'description' => 'Awesome product',!
);!

!
$client = static::createClient();!
$client->request(!
'POST', !
'/products', !
array(), array(), array(), !
json_encode($product)!
);!

!
$this->assertEquals(400, $client->getResponse()->getStatusCode());!
}!
//src/Acme/ApiBundle/Tests/Controller/ApiProductControllerTest.php!

!
public function testGetAction()!
{!
$this->loadFixtures(array(!
'AcmeApiBundleTestsFixturesProduct',!
));!

!
$client = static::createClient();!
$client->request('GET', '/products');!

!
$this->isSuccessful($client->getResponse());!
$response = json_decode($client->getResponse()->getContent());!

!
$this->assertTrue(isset($response->products));!
$this->assertCount(1, $response->products);!

!
$product = $response->products[0];!
$this->assertSame('Product #1', $product->name);!
$this->assertSame(19.90, $product->price);!
$this->assertSame('Awesome product!', $product->description);!
}
//src/Acme/ApiBundle/Tests/Fixtures/Product.php!

!
use AcmeApiBundleEntityProduct as ProductEntity;!

!
use DoctrineCommonPersistenceObjectManager;!
use DoctrineCommonDataFixturesFixtureInterface;!

!
class Product implements FixtureInterface!
{!
public function load(ObjectManager $em)!
{!
$product = new ProductEntity();!
$product->setName('Product #1');!
$product->setPrice(19.90);!
$product->setDescription('Awesome product!');!

!
$em->persist($product);!
$em->flush();!
}!
}!
//src/Acme/ApiBundle/Tests/Controller/ApiProductControllerTest.php!

!
public function testGetSingleAction()!
{!
$this->loadFixtures(array(!
'AcmeApiBundleTestsFixturesProduct',!
));!

!
$client = static::createClient();!
$client->request('GET', '/products/1');!

!
$this->isSuccessful($client->getResponse());!
$response = json_decode($client->getResponse()->getContent());!

!
$this->assertTrue(isset($response->product));!
$this->assertEquals(1, $response->product->id);!
$this->assertSame('Product #1', $response->product->name);!
$this->assertSame(19.90, $response->product->price);!
$this->assertSame(!
'Awesome product!', !
$response->product->description!
);!
}
//src/Acme/ApiBundle/Tests/Controller/ApiProductControllerTest.php!

!
public function testPutAction()!
{!
$this->loadFixtures(array(!
'AcmeApiBundleTestsFixturesProduct',!
));!

!
$product = array(!
'name' => 'New name',!
'price' => 39.90,!
'description' => 'Awesome new description'!
);!

!
$client = static::createClient();!
$client->request(!
'PUT', !
'/products/1', !
array(), array(), array(), !
json_encode($product)!
);!

!
$this->isSuccessful($client->getResponse());!
$this->assertEquals(204, $client->getResponse()->getStatusCode());!
}
//src/Acme/ApiBundle/Tests/Controller/ApiProductControllerTest.php!

!
/**!
* @depends testPutAction!
*/!
public function testPutActionWithVerification()!
{!
$client = static::createClient();!
$client->request('GET', '/products/1');!
$this->isSuccessful($client->getResponse());!
$response = json_decode($client->getResponse()->getContent());!

!
$this->assertTrue(isset($response->product));!
$this->assertEquals(1, $response->product->id);!
$this->assertSame('New name', $response->product->name);!
$this->assertSame(39.90, $response->product->price);!
$this->assertSame(!
'Awesome new description', !
$response->product->description!
);!
}
//src/Acme/ApiBundle/Tests/Controller/ApiProductControllerTest.php!

!
public function testPatchAction()!
{!
$this->loadFixtures(array(!
'AcmeApiBundleTestsFixturesProduct',!
));!

!
$patch = array(!
'price' => 29.90!
);!

!
$client = static::createClient();!
$client->request(!
'PATCH', !
'/products/1', !
array(), array(), array(), !
json_encode($patch)!
);!
!
$this->isSuccessful($client->getResponse());!
$this->assertEquals(204, $client->getResponse()->getStatusCode());!
}
//src/Acme/ApiBundle/Tests/Controller/ApiProductControllerTest.php!

!
public function testDeleteAction()!
{!
$this->loadFixtures(array(!
'AcmeApiBundleTestsFixturesProduct',!
));!

!
$client = static::createClient();!
$client->request('DELETE', '/products/1');!
$this->assertEquals(204, $client->getResponse()->getStatusCode());!
}
Documentation
//src/Acme/ApiBundle/Controller/ApiProductController.php!

!

use NelmioApiDocBundleAnnotationApiDoc;!

!

/**!
* Returns representation of a given product!
*!
* **Response Format**!
*!
*
{!
*
"product": {!
*
"id": 1,!
*
"name": "Product #1",!
*
"price": 19.9,!
*
"description": "Awesome product"!
*
}!
*
}!
*!
* @ApiDoc(!
*
section="Products",!
*
statusCodes={!
*
200="OK",!
*
404="Not Found"!
*
}!
* )!
*/!
public function getSingleAction(Product $product)!
{!
return array('product' => $product);!
}!
Hypermedia?
There’s a bundle
for that™
willdurand/hateoas-bundle
fsc/hateoas-bundle
//src/Acme/ApiBundle/Entity/Product.php;!

!
use JMSSerializerAnnotation as Serializer;!
use FSCHateoasBundleAnnotation as Rest;!
use DoctrineORMMapping as ORM;!

!
/**!
* @ORMEntity!
* @ORMTable(name="product")!
* @SerializerExclusionPolicy("all")!
* @RestRelation(!
*
"self", !
*
href = @RestRoute("acme_api_product_get_single", !
*
parameters = { "id" = ".id" })!
* )!
* @RestRelation(!
*
"products", !
*
href = @RestRoute("acme_api_product_get")!
* )!
*/!
class Product!
{!
...!
}
application/hal+json
GET /orders/523 HTTP/1.1!
Host: example.org!
Accept: application/hal+json!
!

HTTP/1.1 200 OK!
Content-Type: application/hal+json!
!

{!
"_links": {!
"self": { "href": "/orders/523" },!
"invoice": { "href": "/invoices/873" }!
},!
"currency": "USD",!
"total": 10.20!
}
“What needs to be done to make the REST
architectural style clear on the notion that
hypertext is a constraint? In other words, if the
engine of application state (and hence the API)
is not being driven by hypertext, then it cannot
be RESTful and cannot be a REST API. Period.
Is there some broken manual somewhere that
needs to be fixed?”
Roy Fielding
“Anyway, being pragmatic, sometimes a level
2 well done guarantees a good API…”
Daniel Londero
“But don’t call it RESTful. Period.”
Roy Fielding
“Ok.”
Daniel Londero
THANKS
@dlondero

Weitere ähnliche Inhalte

Was ist angesagt?

Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)Antonio Peric-Mazar
 
Web service with Laravel
Web service with LaravelWeb service with Laravel
Web service with LaravelAbuzer Firdousi
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
 
Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5성일 한
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Arc & Codementor
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weiboshaokun
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationAbdul Malik Ikhsan
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发shaokun
 
Introduction à Ruby
Introduction à RubyIntroduction à Ruby
Introduction à RubyMicrosoft
 
Silex, the microframework
Silex, the microframeworkSilex, the microframework
Silex, the microframeworkInviqa
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]Raul Fraile
 
How to driver your webservices with ansible
How to driver your webservices with ansibleHow to driver your webservices with ansible
How to driver your webservices with ansibleGonéri Le Bouder
 
Using WordPress as your application stack
Using WordPress as your application stackUsing WordPress as your application stack
Using WordPress as your application stackPaul Bearne
 
Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - WisemblySymfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - WisemblyGuillaume POTIER
 

Was ist angesagt? (20)

Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
 
Javascript laravel's friend
Javascript laravel's friendJavascript laravel's friend
Javascript laravel's friend
 
PhpSpec extension points
PhpSpec extension pointsPhpSpec extension points
PhpSpec extension points
 
Web service with Laravel
Web service with LaravelWeb service with Laravel
Web service with Laravel
 
REST API Laravel
REST API LaravelREST API Laravel
REST API Laravel
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJS
 
Sf2 wtf
Sf2 wtfSf2 wtf
Sf2 wtf
 
Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5Laravel 로 배우는 서버사이드 #5
Laravel 로 배우는 서버사이드 #5
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weibo
 
The new features of PHP 7
The new features of PHP 7The new features of PHP 7
The new features of PHP 7
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept Implementation
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发
 
Zend framework
Zend frameworkZend framework
Zend framework
 
Introduction à Ruby
Introduction à RubyIntroduction à Ruby
Introduction à Ruby
 
Silex, the microframework
Silex, the microframeworkSilex, the microframework
Silex, the microframework
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
 
How to driver your webservices with ansible
How to driver your webservices with ansibleHow to driver your webservices with ansible
How to driver your webservices with ansible
 
Using WordPress as your application stack
Using WordPress as your application stackUsing WordPress as your application stack
Using WordPress as your application stack
 
Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - WisemblySymfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly
Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly
 

Ähnlich wie REST in practice with Symfony2

Rest in practice con Symfony2
Rest in practice con Symfony2Rest in practice con Symfony2
Rest in practice con Symfony2Daniel Londero
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
OSCON2014 : Quick Introduction to System Tools Programming with Go
OSCON2014 : Quick Introduction to System Tools Programming with GoOSCON2014 : Quick Introduction to System Tools Programming with Go
OSCON2014 : Quick Introduction to System Tools Programming with GoChris McEniry
 
Swift - the future of iOS app development
Swift - the future of iOS app developmentSwift - the future of iOS app development
Swift - the future of iOS app developmentopenak
 
Moving to modules
Moving to modulesMoving to modules
Moving to modulesSean Mize
 
From CakePHP to Laravel
From CakePHP to LaravelFrom CakePHP to Laravel
From CakePHP to LaravelJason McCreary
 
Getting Into FLOW3 (DPC12)
Getting Into FLOW3 (DPC12)Getting Into FLOW3 (DPC12)
Getting Into FLOW3 (DPC12)Robert Lemke
 
api-platform: the ultimate API platform
api-platform: the ultimate API platformapi-platform: the ultimate API platform
api-platform: the ultimate API platformStefan Adolf
 
Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011Jacopo Romei
 
TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13Robert Lemke
 
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the FlowInspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flowmhelmich
 
IPCSE12: Hands on FLOW3
IPCSE12: Hands on FLOW3IPCSE12: Hands on FLOW3
IPCSE12: Hands on FLOW3Robert Lemke
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkChristian Trabold
 
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)James Titcumb
 
IPCSE12: Getting into FLOW3
IPCSE12: Getting into FLOW3IPCSE12: Getting into FLOW3
IPCSE12: Getting into FLOW3Robert Lemke
 
Hacking 101 for developers
Hacking 101 for developersHacking 101 for developers
Hacking 101 for developersTomer Zait
 

Ähnlich wie REST in practice with Symfony2 (20)

Rest in practice con Symfony2
Rest in practice con Symfony2Rest in practice con Symfony2
Rest in practice con Symfony2
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Es.next
Es.nextEs.next
Es.next
 
OSCON2014 : Quick Introduction to System Tools Programming with Go
OSCON2014 : Quick Introduction to System Tools Programming with GoOSCON2014 : Quick Introduction to System Tools Programming with Go
OSCON2014 : Quick Introduction to System Tools Programming with Go
 
Swift - the future of iOS app development
Swift - the future of iOS app developmentSwift - the future of iOS app development
Swift - the future of iOS app development
 
Moving to modules
Moving to modulesMoving to modules
Moving to modules
 
From CakePHP to Laravel
From CakePHP to LaravelFrom CakePHP to Laravel
From CakePHP to Laravel
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Getting Into FLOW3 (DPC12)
Getting Into FLOW3 (DPC12)Getting Into FLOW3 (DPC12)
Getting Into FLOW3 (DPC12)
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
api-platform: the ultimate API platform
api-platform: the ultimate API platformapi-platform: the ultimate API platform
api-platform: the ultimate API platform
 
Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011Symfony CMF - PHP Conference Brazil 2011
Symfony CMF - PHP Conference Brazil 2011
 
TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13
 
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the FlowInspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
InspiringCon15: Bringing TYPO3 Legacy Applications into the Flow
 
IPCSE12: Hands on FLOW3
IPCSE12: Hands on FLOW3IPCSE12: Hands on FLOW3
IPCSE12: Hands on FLOW3
 
TYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase frameworkTYPO3 Extension development using new Extbase framework
TYPO3 Extension development using new Extbase framework
 
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)Crafting Quality PHP Applications (PHP Joburg Oct 2019)
Crafting Quality PHP Applications (PHP Joburg Oct 2019)
 
IPCSE12: Getting into FLOW3
IPCSE12: Getting into FLOW3IPCSE12: Getting into FLOW3
IPCSE12: Getting into FLOW3
 
Hacking 101 for developers
Hacking 101 for developersHacking 101 for developers
Hacking 101 for developers
 

Mehr von Daniel Londero

Random Tips for Remote Working
Random Tips for Remote WorkingRandom Tips for Remote Working
Random Tips for Remote WorkingDaniel Londero
 
Lavorare da casa: siamo pronti?
Lavorare da casa: siamo pronti?Lavorare da casa: siamo pronti?
Lavorare da casa: siamo pronti?Daniel Londero
 
Symfony2, SQL e NoSQL. Assieme. Si può.
Symfony2, SQL e NoSQL. Assieme. Si può.Symfony2, SQL e NoSQL. Assieme. Si può.
Symfony2, SQL e NoSQL. Assieme. Si può.Daniel Londero
 
Lavorare da casa: siamo pronti?
Lavorare da casa: siamo pronti?Lavorare da casa: siamo pronti?
Lavorare da casa: siamo pronti?Daniel Londero
 
Symfony e grandi numeri: si può fare!
Symfony e grandi numeri: si può fare!Symfony e grandi numeri: si può fare!
Symfony e grandi numeri: si può fare!Daniel Londero
 
Enterprise Open Source: Il caso PHP
Enterprise Open Source: Il caso PHPEnterprise Open Source: Il caso PHP
Enterprise Open Source: Il caso PHPDaniel Londero
 

Mehr von Daniel Londero (9)

Magento meets vagrant
Magento meets vagrantMagento meets vagrant
Magento meets vagrant
 
Random Tips for Remote Working
Random Tips for Remote WorkingRandom Tips for Remote Working
Random Tips for Remote Working
 
Lavorare da casa: siamo pronti?
Lavorare da casa: siamo pronti?Lavorare da casa: siamo pronti?
Lavorare da casa: siamo pronti?
 
Symfony2, SQL e NoSQL. Assieme. Si può.
Symfony2, SQL e NoSQL. Assieme. Si può.Symfony2, SQL e NoSQL. Assieme. Si può.
Symfony2, SQL e NoSQL. Assieme. Si può.
 
Lavorare da casa: siamo pronti?
Lavorare da casa: siamo pronti?Lavorare da casa: siamo pronti?
Lavorare da casa: siamo pronti?
 
Io cache, tu database
Io cache, tu databaseIo cache, tu database
Io cache, tu database
 
Unit testing 101
Unit testing 101Unit testing 101
Unit testing 101
 
Symfony e grandi numeri: si può fare!
Symfony e grandi numeri: si può fare!Symfony e grandi numeri: si può fare!
Symfony e grandi numeri: si può fare!
 
Enterprise Open Source: Il caso PHP
Enterprise Open Source: Il caso PHPEnterprise Open Source: Il caso PHP
Enterprise Open Source: Il caso PHP
 

Kürzlich hochgeladen

How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 

Kürzlich hochgeladen (20)

How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 

REST in practice with Symfony2