SlideShare uma empresa Scribd logo
1 de 69
Baixar para ler offline
REST in pratica
con Symfony2
@dlondero
DI SOLITO...
Richardson Maturity Model
NON
PARLIAMO DI...
PARLIAMO DI
COME FARE
COSA CI SERVE
•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
“Tuttavia, essendo pragmatici, a volte anche
un livello 2 ben fatto è garanzia di una buona
API...”
Daniel Londero
“But don’t call it RESTful. Period.”
Roy Fielding
“Ok.”
Daniel Londero
GRAZIE
@dlondero

Mais conteúdo relacionado

Mais procurados

TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13Robert Lemke
 
Shell scripting - By Vu Duy Tu from eXo Platform SEA
Shell scripting - By Vu Duy Tu from eXo Platform SEAShell scripting - By Vu Duy Tu from eXo Platform SEA
Shell scripting - By Vu Duy Tu from eXo Platform SEAThuy_Dang
 
파이썬 플라스크로 배우는 웹프로그래밍 #4 (ABCD)
파이썬 플라스크로 배우는 웹프로그래밍 #4 (ABCD)파이썬 플라스크로 배우는 웹프로그래밍 #4 (ABCD)
파이썬 플라스크로 배우는 웹프로그래밍 #4 (ABCD)성일 한
 
Mocks Enabling Test-Driven Design
Mocks Enabling Test-Driven DesignMocks Enabling Test-Driven Design
Mocks Enabling Test-Driven DesignAlexandre Martins
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming LanguageGiuseppe Arici
 
[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?Radek Benkel
 
Php Reusing Code And Writing Functions
Php Reusing Code And Writing FunctionsPhp Reusing Code And Writing Functions
Php Reusing Code And Writing Functionsmussawir20
 
Introduction to Swift programming language.
Introduction to Swift programming language.Introduction to Swift programming language.
Introduction to Swift programming language.Icalia Labs
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, SwiftYandex
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant TrainingAidIQ
 

Mais procurados (12)

TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13TYPO3 Flow 2.0 Workshop T3BOARD13
TYPO3 Flow 2.0 Workshop T3BOARD13
 
Shell scripting - By Vu Duy Tu from eXo Platform SEA
Shell scripting - By Vu Duy Tu from eXo Platform SEAShell scripting - By Vu Duy Tu from eXo Platform SEA
Shell scripting - By Vu Duy Tu from eXo Platform SEA
 
파이썬 플라스크로 배우는 웹프로그래밍 #4 (ABCD)
파이썬 플라스크로 배우는 웹프로그래밍 #4 (ABCD)파이썬 플라스크로 배우는 웹프로그래밍 #4 (ABCD)
파이썬 플라스크로 배우는 웹프로그래밍 #4 (ABCD)
 
Mocks Enabling Test-Driven Design
Mocks Enabling Test-Driven DesignMocks Enabling Test-Driven Design
Mocks Enabling Test-Driven Design
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming Language
 
perltut
perltutperltut
perltut
 
[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?[PL] Jak nie zostać "programistą" PHP?
[PL] Jak nie zostać "programistą" PHP?
 
Swift Introduction
Swift IntroductionSwift Introduction
Swift Introduction
 
Php Reusing Code And Writing Functions
Php Reusing Code And Writing FunctionsPhp Reusing Code And Writing Functions
Php Reusing Code And Writing Functions
 
Introduction to Swift programming language.
Introduction to Swift programming language.Introduction to Swift programming language.
Introduction to Swift programming language.
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, Swift
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
 

Destaque

Why Use “REST” Architecture for Web Services?
Why Use “REST” Architecture for Web Services?Why Use “REST” Architecture for Web Services?
Why Use “REST” Architecture for Web Services?Arinto Murdopo
 
Level 3 REST Makes Your API Browsable
Level 3 REST Makes Your API BrowsableLevel 3 REST Makes Your API Browsable
Level 3 REST Makes Your API BrowsableMatt Bishop
 
Make Your API Irresistible
Make Your API IrresistibleMake Your API Irresistible
Make Your API Irresistibleduvander
 
jQuery na Prática - Cauê Fajoli
jQuery na Prática - Cauê FajolijQuery na Prática - Cauê Fajoli
jQuery na Prática - Cauê FajoliCaue Fajoli
 
Representational State Transfer (REST) and HATEOAS
Representational State Transfer (REST) and HATEOASRepresentational State Transfer (REST) and HATEOAS
Representational State Transfer (REST) and HATEOASGuy K. Kloss
 
REST - Representational State Transfer
REST - Representational State TransferREST - Representational State Transfer
REST - Representational State TransferPeter R. Egli
 
RestFest - Designing an API for developer happiness
RestFest - Designing an API for developer happinessRestFest - Designing an API for developer happiness
RestFest - Designing an API for developer happinessGarry Shutler
 
What REALLY Differentiates The Best Content Marketers From The Rest
What REALLY Differentiates The Best Content Marketers From The RestWhat REALLY Differentiates The Best Content Marketers From The Rest
What REALLY Differentiates The Best Content Marketers From The RestRoss Simmonds
 

Destaque (9)

Why Use “REST” Architecture for Web Services?
Why Use “REST” Architecture for Web Services?Why Use “REST” Architecture for Web Services?
Why Use “REST” Architecture for Web Services?
 
Rest Teoria E Pratica
Rest Teoria E PraticaRest Teoria E Pratica
Rest Teoria E Pratica
 
Level 3 REST Makes Your API Browsable
Level 3 REST Makes Your API BrowsableLevel 3 REST Makes Your API Browsable
Level 3 REST Makes Your API Browsable
 
Make Your API Irresistible
Make Your API IrresistibleMake Your API Irresistible
Make Your API Irresistible
 
jQuery na Prática - Cauê Fajoli
jQuery na Prática - Cauê FajolijQuery na Prática - Cauê Fajoli
jQuery na Prática - Cauê Fajoli
 
Representational State Transfer (REST) and HATEOAS
Representational State Transfer (REST) and HATEOASRepresentational State Transfer (REST) and HATEOAS
Representational State Transfer (REST) and HATEOAS
 
REST - Representational State Transfer
REST - Representational State TransferREST - Representational State Transfer
REST - Representational State Transfer
 
RestFest - Designing an API for developer happiness
RestFest - Designing an API for developer happinessRestFest - Designing an API for developer happiness
RestFest - Designing an API for developer happiness
 
What REALLY Differentiates The Best Content Marketers From The Rest
What REALLY Differentiates The Best Content Marketers From The RestWhat REALLY Differentiates The Best Content Marketers From The Rest
What REALLY Differentiates The Best Content Marketers From The Rest
 

Semelhante a Rest in practice con Symfony2

REST in practice with Symfony2
REST in practice with Symfony2REST in practice with Symfony2
REST in practice with Symfony2Daniel Londero
 
Hacking 101 for developers
Hacking 101 for developersHacking 101 for developers
Hacking 101 for developersTomer Zait
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)James Titcumb
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)James Titcumb
 
IPCSE12: Hands on FLOW3
IPCSE12: Hands on FLOW3IPCSE12: Hands on FLOW3
IPCSE12: Hands on FLOW3Robert Lemke
 
Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Robert Lemke
 
Hands on FLOW3 (DPC12)
Hands on FLOW3 (DPC12)Hands on FLOW3 (DPC12)
Hands on FLOW3 (DPC12)Robert Lemke
 
Treatment, Architecture and Threads
Treatment, Architecture and ThreadsTreatment, Architecture and Threads
Treatment, Architecture and ThreadsMathias Seguy
 
Commenting in Agile Development
Commenting in Agile DevelopmentCommenting in Agile Development
Commenting in Agile DevelopmentJan Rybák Benetka
 
Desymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus BundlesDesymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus BundlesAlbert Jessurum
 
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
 
オレオレSecurityバンドル作っちゃいました
オレオレSecurityバンドル作っちゃいましたオレオレSecurityバンドル作っちゃいました
オレオレSecurityバンドル作っちゃいましたKatsuhiro Ogawa
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)James Titcumb
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 

Semelhante a Rest in practice con Symfony2 (20)

REST in practice with Symfony2
REST in practice with Symfony2REST in practice with Symfony2
REST in practice with Symfony2
 
Symfony2. Database and Doctrine
Symfony2. Database and DoctrineSymfony2. Database and Doctrine
Symfony2. Database and Doctrine
 
Doctrine in FLOW3
Doctrine in FLOW3Doctrine in FLOW3
Doctrine in FLOW3
 
Hacking 101 for developers
Hacking 101 for developersHacking 101 for developers
Hacking 101 for developers
 
Migrare da symfony 1 a Symfony2
 Migrare da symfony 1 a Symfony2  Migrare da symfony 1 a Symfony2
Migrare da symfony 1 a Symfony2
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
IPCSE12: Hands on FLOW3
IPCSE12: Hands on FLOW3IPCSE12: Hands on FLOW3
IPCSE12: Hands on FLOW3
 
Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0
 
Hands on FLOW3 (DPC12)
Hands on FLOW3 (DPC12)Hands on FLOW3 (DPC12)
Hands on FLOW3 (DPC12)
 
Treatment, Architecture and Threads
Treatment, Architecture and ThreadsTreatment, Architecture and Threads
Treatment, Architecture and Threads
 
Commenting in Agile Development
Commenting in Agile DevelopmentCommenting in Agile Development
Commenting in Agile Development
 
Desymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus BundlesDesymfony 2011 - Habemus Bundles
Desymfony 2011 - Habemus Bundles
 
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
 
オレオレSecurityバンドル作っちゃいました
オレオレSecurityバンドル作っちゃいましたオレオレSecurityバンドル作っちゃいました
オレオレSecurityバンドル作っちゃいました
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 

Mais de 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
 

Mais de 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
 

Último

Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 

Último (20)

Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 

Rest in practice con Symfony2