SlideShare a Scribd company logo
Sylius and API Platform


The story of integration
Sylius and Api Platform The story of integration
Sylius and Api Platform The story of integration
Foreword
Application & Infrastructure


Hexagonal
3 topcis


Application, API Design, Testing
What did we want to
achieve?
Become modern,


API-
fi
rst e-commerce
Deliver a new quality in the
headless e-commerce
Be closer to Symfony
Always up-to-date
documentation
Application architecture
Photo by Marc-Olivier Jodoin on Unsplash
How to preserve Api Platform
usage easiness and Sylius
fl
exibility?
How to handle typical create,
update and read operations?
CRUD
Easy to setup
Easy to setup


Easy to use
Easy to setup


Easy to use


Easy to extend
Familiar for most developers
How?
#[ORMEntity
]

#[ApiResource
]

class Produc
t

{

/** */
}
Sylius and Api Platform The story of integration
Cons
Harder to bend to business
expectations
How to handle business
expectations?
Commands
Super
fl
exible


Gives possible to defer execution


Decouples layers
Infrastructure
Application
Infrastructure
Command
Application
Infrastructure
Handler
Command
Application
Infrastructure
Handler
Command
Messenger
Application
How?
class AddItemToCar
t

{

public ProductVariant $productVariant
;

public int $quantity;
}
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{

$cart = $this->cartContext->getCart()
;

$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart;
}

}
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{
$cart = $this->cartContext->getCart()
;

$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart
;

}

}
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{

$cart = $this->cartContext->getCart()
;

$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart
;

}

}
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{

$cart = $this->cartContext->getCart()
;

$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart
;

}

}
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{

$cart = $this->cartContext->getCart()
;

$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart;
}

}
One command


One handler
Transaction & Validation
Middleware's
Super
fl
exible


Gives possible to defer execution


Decouples layers
Are they separated?
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{

$cart = $this->cartContext->getCart()
;

$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart;
}

}
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{
$cart = $this->cartContext->getCart()
;

$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart
;

}

}
class AddItemToCar
t

{

public Order $order;
public ProductVariant $productVariant
;

public int $quantity
;

}
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{
$cart = $command->order
;

$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart
;

}

}
No session/request data


in handlers and below
Command should contain


all information required


to perform an action
Super
fl
exible


Gives possible to defer execution or
send it outside


Decouples layers
Can we defer it?
class AddItemToCar
t

{

public Order $order
;

public ProductVariant $productVariant
;

public int $quantity
;

}
class AddItemToCar
t

{

public string $orderToken;
public string $productVariantCode
;

public int $quantity;
}
final class AddItemToCartHandle
r

{

public function __invoke(AddItemToCart $command): Orde
r

{
$productVariant = $this->productVariantRepository->findOneBy
(

['code' => $addItemToCart->productVariantCode
]

)
;

$cart = $this->orderRepository->findCartByTokenValue
(

$addItemToCart->orderTokenValu
e

);
$cartItem = $this->cartItemFactory->createNew()
;

$cartItem->setVariant($command->productVariant)
;

$this->orderItemQuantityModifier->modify
(

$cartItem,
 

$command->quantit
y

)
;

$this->orderModifier->addToOrder($cart, $cartItem)
;

return $cart
;

}

}
Commands with raw data only
But where this data came from?
Sylius and Api Platform The story of integration
Sylius and Api Platform The story of integration
Sylius and Api Platform The story of integration
DataTransformer?
Every “new” keyword couples you to
given implementation
Not relevant for 87% of developers
Faked Data Institute ®
Command enrichment!
class AddItemToCart implements OrderTokenValueAwareInterfac
e

{

public ?string $orderTokenValue
;

public string $productVariantCode
;

public int $quantity
;

public function getOrderTokenValue(): ?strin
g

{

return $this->orderTokenValue
;

}

public function setOrderTokenValue(?string $orderTokenValue): voi
d

{

$this->orderTokenValue = $orderTokenValue
;

}

}
final class OrderTokenValueAwareInputCommandDataTransforme
r

implements CommandDataTransformerInterfac
e

{

public function transform($object, string $to, array $context = []
)

{

/** @var OrderInterface $cart *
/

$cart = $context['object_to_populate']
;

$object->setOrderTokenValue($cart->getTokenValue())
;

return $object
;

}

public function supportsTransformation($object): boo
l

{

return $object instanceof OrderTokenValueAwareInterface
;

}

}
DataTransformer


vs


DataEnrichment
Current user
Current user


Current locale
Current user


Current locale


Current channel(Sylius speci
fi
c)
Current user


Current locale


Current channel(Sylius speci
fi
c)


Current order
Current user


Current locale


Current channel(Sylius speci
fi
c)


Current order
No session/request data


in handlers and below
Enrichments provide better class
extendibility for framework
Interfaces as contracts
Cons
More complicated architecture


Steeper learning curve
API Design
Photo by Halacious on Unsplash
How to model our API?
IRI usage
{

"@context": "/api/v2/contexts/ProductVariant"
,

"@id": "/api/v2/shop/product-variants/MUG_BLUE"
,

"@type": "ProductVariant"
,

"id": @integer@
,

"onHand": 10
,

"code": "MUG_BLUE"
,

"currentStock": 5
,

"product": "/api/v2/shop/products/MUG"
,

"optionValues":
[

"/api/v2/shop/product-option-values/COLOR_BLUE
"

]
,

"translations": {...}
,

"price": 2000
,

"originalPrice": 2000
,

"inStock": tru
e

}
{

"@context": "/api/v2/contexts/ProductVariant"
,

"@id": "/api/v2/shop/product-variants/MUG_BLUE"
,

"@type": "ProductVariant"
,

"id": @integer@
,

"onHand": 10
,

"code": "MUG_BLUE"
,

"currentStock": 5
,

"product": "/api/v2/shop/products/MUG"
,

"optionValues":
[

"/api/v2/shop/product-option-values/COLOR_BLUE
"

]
,

"translations": {...}
,

"price": 2000
,

"originalPrice": 2000
,

"inStock": tru
e

}
{

"@context": "/api/v2/contexts/ProductVariant"
,

"@id": "/api/v2/shop/product-variants/MUG_BLUE"
,

"@type": "ProductVariant"
,

"id": @integer@
,

"onHand": 10
,

"code": "MUG_BLUE"
,

"currentStock": 5
,

"product": "/api/v2/shop/products/MUG"
,

"optionValues":
[

"/api/v2/shop/product-option-values/COLOR_BLUE
"

]
,

"translations": {...}
,

"price": 2000
,

"originalPrice": 2000
,

"inStock": tru
e

}
{

"@context": "/api/v2/contexts/ProductVariant"
,

"@id": "/api/v2/shop/product-variants/MUG_BLUE"
,

"@type": "ProductVariant"
,

"id": @integer@
,

"onHand": 10
,

"code": "MUG_BLUE"
,

"currentStock": 5
,

"product": "/api/v2/shop/products/MUG"
,

"optionValues":
[

"/api/v2/shop/product-option-values/COLOR_BLUE
"

]
,

"translations": {...}
,

"price": 2000
,

"originalPrice": 2000
,

"inStock": tru
e

}
class AddItemToCar
t

{

public string $orderToken;
public string $productVariantCode
;

public int $quantity;
}
Sylius and Api Platform The story of integration
Sylius and Api Platform The story of integration
How?
<class name="SyliusBundleApiBundleCommandCartAddItemToCart">
<attribute name="productVariantCode
"

serialized-name="productVariant
"

>

<group>shop:cart:add_item</group
>

</attribute
>

<attribute name="quantity"
>

<group>shop:cart:add_item</group
>

</attribute
>

</class>
class AddItemToCart implements IriToIdenti
fi
erConversionAwareInterfac
e

{

public string $orderToken
;

public string $productVariantCode
;

public int $quantity
;

}
Database =/= resource
Reset password
Sylius and Api Platform The story of integration
<resource
 

class=“SyliusBundleApiBundleCommandResetPassword
"

shortName="ResetPasswordRequest"
>

<collectionOperations
>

<collectionOperation name="shop_create_reset_password_request"
>

<attribute name="method">POST</attribute
>

<attribute name="path">/reset-password-requests</attribute
>

<attribute name=“input"
>

SyliusBundleApiBundleCommandRequestResetPasswordToke
n

</attribute
>

<attribute name="output">false</attribute
>

<attribute name="status">202</attribute
>

</collectionOperation
>

</collectionOperations
>

<itemOperations
>

<itemOperation name="shop_update_reset_password_request"
>

<attribute name="method">PATCH</attribute
>

<attribute name="path">/reset-password-requests/{id}</attribute
>

<attribute name=“input"
>

SyliusBundleApiBundleCommandResetPasswor
d

</attribute
>

<attribute name="output">false</attribute
>

<attribute name="status">202</attribute
>

</itemOperation
>

</itemOperations
>

</resource>
<resource
 

class=“SyliusBundleApiBundleCommandResetPassword
"

shortName="ResetPasswordRequest"
>

<collectionOperations
>

<collectionOperation name="shop_create_reset_password_request">
<attribute name="method">POST</attribute
>

<attribute name="path">/reset-password-requests</attribute
>

<attribute name=“input"
>

SyliusBundleApiBundleCommandRequestResetPasswordToke
n

</attribute
>

<attribute name="output">false</attribute
>

<attribute name="status">202</attribute
>

</collectionOperation
>

</collectionOperations
>

<itemOperations
>

<itemOperation name="shop_update_reset_password_request"
>

<attribute name="method">PATCH</attribute
>

<attribute name="path">/reset-password-requests/{id}</attribute
>

<attribute name=“input"
>

SyliusBundleApiBundleCommandResetPasswor
d

</attribute
>

<attribute name="output">false</attribute
>

<attribute name="status">202</attribute
>

</itemOperation
>

</itemOperations
>

</resource>
<resource
 

class=“SyliusBundleApiBundleCommandResetPassword
"

shortName="ResetPasswordRequest"
>

<collectionOperations
>

<collectionOperation name="shop_create_reset_password_request"
>

<attribute name="method">POST</attribute
>

<attribute name="path">/reset-password-requests</attribute
>

<attribute name=“input"
>

SyliusBundleApiBundleCommandRequestResetPasswordToke
n

</attribute
>

<attribute name="output">false</attribute
>

<attribute name="status">202</attribute
>

</collectionOperation
>

</collectionOperations
>

<itemOperations
>

<itemOperation name="shop_update_reset_password_request">
<attribute name="method">PATCH</attribute
>

<attribute name="path">/reset-password-requests/{id}</attribute
>

<attribute name=“input"
>

SyliusBundleApiBundleCommandResetPasswor
d

</attribute
>

<attribute name="output">false</attribute
>

<attribute name="status">202</attribute
>

</itemOperation
>

</itemOperations
>

</resource>
<resource
 

class=“SyliusBundleApiBundleCommandResetPassword
"

shortName="ResetPasswordRequest"
>

<collectionOperations
>

<collectionOperation name="shop_create_reset_password_request"
>

<attribute name="method">POST</attribute
>

<attribute name="path">/reset-password-requests</attribute
>

<attribute name=“input"
>

SyliusBundleApiBundleCommandRequestResetPasswordToke
n

</attribute
>

<attribute name="output">false</attribute
>

<attribute name="status">202</attribute
>

</collectionOperation
>

</collectionOperations
>

<itemOperations
>

<itemOperation name="shop_update_reset_password_request"
>

<attribute name="method">PATCH</attribute
>

<attribute name="path">/reset-password-requests/{id}</attribute
>

<attribute name=“input"
>

SyliusBundleApiBundleCommandResetPasswor
d

</attribute
>

<attribute name="output">false</attribute
>

<attribute name="status">202</attribute
>

</itemOperation
>

</itemOperations
>

</resource>
Sylius and Api Platform The story of integration
Testing Architecture
Photo by Danist Soh on Unsplash
Sylius aka BDD Warriors
Sylius and Api Platform The story of integration
1500+ scenario
s

17000+ steps
~2000 scenario
s

~22000 steps
Behat
Business oriented scenarios
Gherkin notation
Feature: Signing in to the stor
e

In order to view my order
s

As a Visito
r

I want to be able to log in to the stor
e

Background:
Given there is a user "ted@example.com" identi
fi
ed by "bear
"

Scenario: Sign in with email and passwor
d

When I want to log in with the "ted@example.com" email and the "bear" passwor
d

Then I should be logged in
Great to keep conversation
about features
Abstraction over the
implementation
How to test our new
infrastructure?
@customer_logi
n

Feature: Signing in to the stor
e

In order to view my order
s

As a Visito
r

I want to be able to log in to the stor
e

Background
:

Given the store operates on a single channel in "United States
"

And there is a user "ted@example.com" identi
fi
ed by "bear
"

@ui @ap
i

Scenario: Sign in with email and passwor
d

When I want to log i
n

And I specify the username as "ted@example.com
"

And I specify the password as "bear
"

And I log i
n

Then I should be logged in
@customer_logi
n

Feature: Signing in to the stor
e

In order to view my order
s

As a Visito
r

I want to be able to log in to the stor
e

Background
:

Given the store operates on a single channel in "United States
"

And there is a user "ted@example.com" identi
fi
ed by "bear
"

@ui @api
Scenario: Sign in with email and passwor
d

When I want to log i
n

And I specify the username as "ted@example.com
"

And I specify the password as "bear
"

And I log i
n

Then I should be logged in
@customer_logi
n

Feature: Signing in to the stor
e

In order to view my order
s

As a Visito
r

I want to be able to log in to the stor
e

Background
:

Given the store operates on a single channel in "United States
"

And there is a user "ted@example.com" identi
fi
ed by "bear
"

@ui @ap
i

Scenario: Sign in with email and passwor
d

When I want to log i
n

And I specify the username as "ted@example.com
"

And I specify the password as "bear
"

And I log i
n

Then I should be logged in
@customer_logi
n

Feature: Signing in to the stor
e

In order to view my order
s

As a Visito
r

I want to be able to log in to the stor
e

Background
:

Given the store operates on a single channel in "United States
"

And there is a user "ted@example.com" identi
fi
ed by "bear
"

@ui @ap
i

Scenario: Sign in with email and passwor
d

When I want to log i
n

And I specify the username as "ted@example.com
"

And I specify the password as "bear
"

And I log i
n

Then I should be logged in
@customer_logi
n

Feature: Signing in to the stor
e

In order to view my order
s

As a Visito
r

I want to be able to log in to the stor
e

Background
:

Given the store operates on a single channel in "United States
"

And there is a user "ted@example.com" identi
fi
ed by "bear
"

@ui @ap
i

Scenario: Sign in with email and passwor
d

When I want to log i
n

And I specify the username as "ted@example.com
"

And I specify the password as "bear
"

And I log i
n

Then I should be logged in
@customer_logi
n

Feature: Signing in to the stor
e

In order to view my order
s

As a Visito
r

I want to be able to log in to the stor
e

Background:
Given the store operates on a single channel in "United States
"

And there is a user "ted@example.com" identi
fi
ed by "bear
"

@ui @ap
i

Scenario: Sign in with email and passwor
d

When I want to log i
n

And I specify the username as "ted@example.com
"

And I specify the password as "bear
"

And I log i
n

Then I should be logged in
/*
*

* @When I log i
n

*
/

public function iLogIn(
)

{

$this->loginPage->logIn()
;

}
@customer_logi
n

Feature: Signing in to the stor
e

In order to view my order
s

As a Visito
r

I want to be able to log in to the stor
e

Background:
Given the store operates on a single channel in "United States
"

And there is a user "ted@example.com" identi
fi
ed by "bear
"

@ui @api
Scenario: Sign in with email and passwor
d

When I want to log i
n

And I specify the username as "ted@example.com
"

And I specify the password as "bear
"

And I log i
n

Then I should be logged in
/*
*

* @When I log i
n

*
/

public function iLogIn(): voi
d

{

$this->client->call()
;

}
Behat as migration tool
Cons
Implementation overhead


New syntax to be familiar with
We didn’t seen our APIs
that much
How to keep contracts and
design our APIs?
PHPUnit
Whole response easily visible
{

"@context": "/api/v2/contexts/Payment"
,

"@id": "/api/v2/shop/payments/@integer@"
,

"@type": "Payment"
,

"order": "/api/v2/shop/orders/nAWw2jewpA"
,

"id": @integer@
,

"method":
{

"@id": "/api/v2/shop/payment-methods/CASH_ON_DELIVERY"
,

"@type": "PaymentMethod"
,

"name": "Cash on delivery
"

}
,

"currencyCode": "USD"
,

"amount": 6500
,

"state": "new"
,

"details": []
,

"createdAt": "@string@"
,

"updatedAt": "@string@
"

}
It will fail if anything will be
removed or added
Easy to setup and maintain
lchrusciel/ApiTestCase


or


Internal Api Platform ApiTestCase
Simpli
fi
ed tests only
Mostly one API call only


Arrangement => DB
fi
xtures + commands


No business
fl
ow checks
/** @test *
/

public function it_gets_details_about_product_variant(): voi
d

{

$this->loadFixturesFromFile('test_data.yaml')
;

$this->client->request
(

'GET'
,

'/api/v2/shop/product-variants/MUG_BLUE',
 

[],
 

[],
 

self::CONTENT_TYPE_HEADE
R

)
;

$response = $this->client->getResponse()
;

$this->assertResponse($response, 'get_product_variant_response', Response::HTTP_OK)
;

}
/** @test *
/

public function it_gets_details_about_product_variant(): voi
d

{

$this->loadFixturesFromFile('test_data.yaml')
;

$this->client->request
(

'GET'
,

'/api/v2/shop/product-variants/MUG_BLUE',
 

[],
 

[],
 

self::CONTENT_TYPE_HEADE
R

)
;

$response = $this->client->getResponse()
;

$this->assertResponse($response, 'get_product_variant_response', Response::HTTP_OK)
;

}
/** @test *
/

public function it_gets_details_about_product_variant(): voi
d

{

$this->loadFixturesFromFile('test_data.yaml')
;

$this->client->request
(

'GET'
,

'/api/v2/shop/product-variants/MUG_BLUE',
 

[],
 

[],
 

self::CONTENT_TYPE_HEADE
R

)
;

$response = $this->client->getResponse()
;

$this->assertResponse($response, 'get_product_variant_response', Response::HTTP_OK)
;

}
/** @test *
/

public function it_gets_details_about_product_variant(): voi
d

{

$this->loadFixturesFromFile('test_data.yaml')
;

$this->client->request
(

'GET'
,

'/api/v2/shop/product-variants/MUG_BLUE',
 

[],
 

[],
 

self::CONTENT_TYPE_HEADE
R

)
;

$response = $this->client->getResponse()
;

$this->assertResponse($response, 'get_product_variant_response', Response::HTTP_OK)
;

}
/** @test */
public function it_gets_details_about_product_variant(): voi
d

{

$this->loadFixturesFromFile('test_data.yaml')
;

$this->client->request
(

'GET'
,

'/api/v2/shop/product-variants/MUG_BLUE',
 

[],
 

[],
 

self::CONTENT_TYPE_HEADE
R

)
;

$response = $this->client->getResponse()
;

$this->assertResponse($response, 'get_product_variant_response', Response::HTTP_OK)
;

}
{

"@context": "/api/v2/contexts/ProductVariant"
,

"@id": "/api/v2/shop/product-variants/MUG_BLUE"
,

"@type": "ProductVariant"
,

"id": @integer@
,

"onHand": 10
,

"code": "MUG_BLUE"
,

"currentStock": 5
,

"product": "/api/v2/shop/products/MUG"
,

"optionValues":
[

"/api/v2/shop/product-option-values/COLOR_BLUE
"

]
,

"translations":
{

"en_US":
{

"@id": "/api/v2/shop/product-variant-translation/@integer@"
,

"@type": "ProductVariantTranslation"
,

"id": @integer@
,

"name": "Blue Mug"
,

"locale": "en_US
"

}

}
,

"price": 2000
,

"originalPrice": 2000
,

"inStock": tru
e

}
Cons
Developer oriented usage
Summary
What are the pros & cons of
this integration?
Sylius and Api Platform The story of integration
https://master.demo.sylius.com/api/v2/docs
@Sylius
Thank you!
@lukaszchrusciel

More Related Content

PPT
Spring Boot in Action
PPTX
Introduction à spring boot
PPTX
Introduction to spring boot
PDF
Spring Boot
PPTX
Introduction to Spring Boot
PDF
Spring boot introduction
PPT
Collections Framework
PDF
Présentation Angular 2
Spring Boot in Action
Introduction à spring boot
Introduction to spring boot
Spring Boot
Introduction to Spring Boot
Spring boot introduction
Collections Framework
Présentation Angular 2

What's hot (20)

PDF
Events and Listeners in Android
PPTX
Spring boot
PDF
React js
PPTX
AngularJS Architecture
PDF
Swagger With REST APIs.pptx.pdf
PDF
Introduction to Spring Boot
PDF
Introduction to thymeleaf
PPTX
Introduction to react and redux
PDF
Spring MVC Framework
PPTX
Spring Boot and REST API
PDF
Web Development with Python and Django
PPTX
CMS Testing Strategy & CQ5 CMS
PPTX
Spring Boot
PPTX
Spring boot
PPTX
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
PDF
Introduction to Spring WebFlux #jsug #sf_a1
PDF
Laravel Design Patterns
PPTX
Spring boot - an introduction
PPTX
Spring boot
PPTX
Its time to React.js
Events and Listeners in Android
Spring boot
React js
AngularJS Architecture
Swagger With REST APIs.pptx.pdf
Introduction to Spring Boot
Introduction to thymeleaf
Introduction to react and redux
Spring MVC Framework
Spring Boot and REST API
Web Development with Python and Django
CMS Testing Strategy & CQ5 CMS
Spring Boot
Spring boot
Java Spring framework, Dependency Injection, DI, IoC, Inversion of Control
Introduction to Spring WebFlux #jsug #sf_a1
Laravel Design Patterns
Spring boot - an introduction
Spring boot
Its time to React.js
Ad

Similar to Sylius and Api Platform The story of integration (20)

PDF
Hexagonal architecture
PDF
Doctrine For Beginners
PDF
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
PDF
Protocol-Oriented Programming in Swift
PDF
Working With The Symfony Admin Generator
PPTX
Event Sourcing with php
PDF
Crafting Quality PHP Applications (Bucharest Tech Week 2017)
PDF
Application Layer in PHP
PDF
How to switch stack without downtime
PDF
DDD on example of Symfony (Webcamp Odessa 2014)
PDF
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
PDF
How to code to code less
PDF
Dart for Java Developers
PPTX
PPTX
Code Generation in Magento 2
PDF
Need for Speed: Removing speed bumps in API Projects
PDF
Crafting Quality PHP Applications (PHP Benelux 2018)
PPTX
AEM & eCommerce integration
PDF
Michiel Overeem (AFAS) - Enterprise software schaalbaar maken met Service Fab...
PPT
Developing A Real World Logistic Application With Oracle Application - UKOUG ...
Hexagonal architecture
Doctrine For Beginners
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Protocol-Oriented Programming in Swift
Working With The Symfony Admin Generator
Event Sourcing with php
Crafting Quality PHP Applications (Bucharest Tech Week 2017)
Application Layer in PHP
How to switch stack without downtime
DDD on example of Symfony (Webcamp Odessa 2014)
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
How to code to code less
Dart for Java Developers
Code Generation in Magento 2
Need for Speed: Removing speed bumps in API Projects
Crafting Quality PHP Applications (PHP Benelux 2018)
AEM & eCommerce integration
Michiel Overeem (AFAS) - Enterprise software schaalbaar maken met Service Fab...
Developing A Real World Logistic Application With Oracle Application - UKOUG ...
Ad

More from Łukasz Chruściel (20)

PDF
2024 PHPCon - Symfony background processing
PDF
Wprowadzenie do fundamentów Sylius 2.0
PDF
APIP 2024 - All the Challenges of Sylius Migration to API Platform 3.pdf [REU...
PDF
APIP 2024 - All the Challenges of Sylius Migration to API Platform 3.pdf
PDF
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
PDF
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
PDF
Unveiling the Future: Sylius 2.0 New Features
PDF
ConFoo 2024 - Need for Speed: Removing speed bumps in API Projects
PDF
ConFoo 2024 - Sylius 2.0, top-notch eCommerce for customizable solution
PDF
SyliusCon - Typical pitfalls of Sylius development.pdf
PDF
SymfonyLive Online 2023 - Is SOLID dead? .pdf
PDF
Worldwide Software Architecture Summit'23 - BDD and why most of us do it wron...
PDF
4Developers - Rozterki i decyzje.pdf
PDF
4Developers - Sylius CRUD generation revisited.pdf
PDF
BoilingFrogs - Rozterki i decyzje. Czego się nauczyliśmy projektując API Syliusa
PDF
What we've learned designing new Sylius API
PDF
How to optimize background processes.pdf
PDF
SymfonyCon - Dilemmas and decisions..pdf
PDF
How to optimize background processes - when Sylius meets Blackfire
PDF
Symfony World - Symfony components and design patterns
2024 PHPCon - Symfony background processing
Wprowadzenie do fundamentów Sylius 2.0
APIP 2024 - All the Challenges of Sylius Migration to API Platform 3.pdf [REU...
APIP 2024 - All the Challenges of Sylius Migration to API Platform 3.pdf
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Unveiling the Future: Sylius 2.0 New Features
ConFoo 2024 - Need for Speed: Removing speed bumps in API Projects
ConFoo 2024 - Sylius 2.0, top-notch eCommerce for customizable solution
SyliusCon - Typical pitfalls of Sylius development.pdf
SymfonyLive Online 2023 - Is SOLID dead? .pdf
Worldwide Software Architecture Summit'23 - BDD and why most of us do it wron...
4Developers - Rozterki i decyzje.pdf
4Developers - Sylius CRUD generation revisited.pdf
BoilingFrogs - Rozterki i decyzje. Czego się nauczyliśmy projektując API Syliusa
What we've learned designing new Sylius API
How to optimize background processes.pdf
SymfonyCon - Dilemmas and decisions..pdf
How to optimize background processes - when Sylius meets Blackfire
Symfony World - Symfony components and design patterns

Recently uploaded (20)

PPTX
L1 - Introduction to python Backend.pptx
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
System and Network Administration Chapter 2
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPT
Introduction Database Management System for Course Database
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
ai tools demonstartion for schools and inter college
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Nekopoi APK 2025 free lastest update
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPTX
history of c programming in notes for students .pptx
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
L1 - Introduction to python Backend.pptx
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
System and Network Administration Chapter 2
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
CHAPTER 2 - PM Management and IT Context
Which alternative to Crystal Reports is best for small or large businesses.pdf
Odoo Companies in India – Driving Business Transformation.pdf
Introduction Database Management System for Course Database
ISO 45001 Occupational Health and Safety Management System
Softaken Excel to vCard Converter Software.pdf
ai tools demonstartion for schools and inter college
Internet Downloader Manager (IDM) Crack 6.42 Build 41
How to Migrate SBCGlobal Email to Yahoo Easily
How to Choose the Right IT Partner for Your Business in Malaysia
Nekopoi APK 2025 free lastest update
Design an Analysis of Algorithms II-SECS-1021-03
history of c programming in notes for students .pptx
Wondershare Filmora 15 Crack With Activation Key [2025
ManageIQ - Sprint 268 Review - Slide Deck
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx

Sylius and Api Platform The story of integration