Download - CQRS v rohlik.cz
![Page 1: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/1.jpg)
CQRS v@ProchazkaFilip
![Page 2: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/2.jpg)
Co si povíme- Na čem běží Rohlik.cz- Co je ORM, a proč ho používat- Seznámení s Doctrine 2- Seznámení s ElasticSearch- CQRS
![Page 3: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/3.jpg)
Na čem běžíme
![Page 4: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/4.jpg)
Na čem běžíme: platforma
- PHP-FPM- NGINX- Percona (MySQL)- Redis- RabbitMQ- ElasticSearch
![Page 5: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/5.jpg)
Na čem běžíme: aplikace
- Nette Framework- Doctrine 2 ORM- Symfony komponenty- React.PHP
![Page 6: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/6.jpg)
Na čem běžíme: podpůrné technologie
- NewRelic- Papertrail- Travis CI- GitHub- Slack- Composer- ...
![Page 7: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/7.jpg)
Proč používat ORM
![Page 8: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/8.jpg)
“Nejhloupější” modelyclass OrdersModel{
private $db;function __construct(DbConnection $db) {
$this->db = $db;}
function findAll() {return $this->db->query("SELECT * FROM orders");
}
![Page 9: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/9.jpg)
ORM?
Object-relational mapping is a programming technique for converting data between incompatible type systems in object-oriented programming languages.
via https://en.wikipedia.org/wiki/Object-relational_mapping
![Page 10: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/10.jpg)
Pseudo-ORMclass OrdersModel{
private $db;function __construct(DbConnection $db) {
$this->db = $db;}function findAll() {
return $this->mapResult($this->db->query("SELECT * FROM orders")
);}
![Page 11: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/11.jpg)
Active Record$user = User::create(['name' => 'Tito']);
$user = User::find_by_name('Tito');
$user->name = 'Tito Jr';$user->save();
$user->delete();
![Page 12: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/12.jpg)
SOLID
● Single responsibility principle● Open/closed principle● Liskov substitution principle● Interface segregation principle● Dependency inversion principle
![Page 13: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/13.jpg)
Data Mapper
$user = new User('Pepa');
$em->persist($user);$em->flush();
$user = $em->find(User::class, 1);
![Page 14: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/14.jpg)
Data Mapper- Můžu mít kompletně objektový model- Entity jsou objekty, které se nestarají o persistenci- To že je entita uložena v DB je “detail”
![Page 15: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/15.jpg)
Doctrine 2 ORM
![Page 16: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/16.jpg)
Doctrine: architektura
DBAL
Doctrine ORM
Entities
Services
Facades
Database
EntityManager
Repository
![Page 17: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/17.jpg)
Doctrine: DBAL
- Obálka nad PDO- Abstrakce mezi databázemi- Primitivní datové typy- Schéma- Snadnější DB migrace
![Page 18: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/18.jpg)
Doctrine:
- Persistence entit- Událostní systém (Eventy)- UnitOfWork- Identity Mapa- DQL
Doctrine ORM
![Page 19: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/19.jpg)
Doctrine:
class Product{ /** @var int */ private $id; /** @var string */ private $name;
Entities
![Page 20: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/20.jpg)
Doctrine:
/** @Entity @Table(name="products") **/class Product{ /** @Id @Column(type="integer") @GeneratedValue **/ private $id; /** @Column(type="string") **/ private $name;
Entities
![Page 21: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/21.jpg)
Doctrine: Services
- Logické jednotky a operace v aplikaci- Může být více services na jednu entitu- Může být více entit na jednu service
![Page 22: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/22.jpg)
Doctrine: DQL
SELECT b, e, rFROM Bug bJOIN b.engineer eJOIN b.reporter rORDER BY b.created DESC
![Page 23: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/23.jpg)
Doctrine: Facades
- Zapouzdřují services- Jedna metoda využívá několik service
![Page 24: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/24.jpg)
Doctrine: nevýhody
- Je nutné chápat OOP- Je nutné chápat DataMapper a spol.- Leaky abstraction- Výkon
![Page 25: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/25.jpg)
ElasticSearch
![Page 26: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/26.jpg)
ElasticSearch
- schema-less search engine- umí schéma- škálování za hubičku- REST api
![Page 27: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/27.jpg)
ElasticSearch
- obsahuje index- indexy obsahují typy- typy obsahují dokumenty- dokumenty mají id a fieldy
GET /rohlikcz/product/123
![Page 28: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/28.jpg)
ElasticSearch: (de)normalizace
- app -> databáze = normalizace- méně dat- méně duplikací- horší na dotazování
- databáze -> ES = denormalizace- duplikace, duplikace, duplikace- so fucking fast
![Page 29: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/29.jpg)
ElasticSearchGET /megacorp/employee/_search?q=last_name:Smith{ ... "hits": { "total": 2, "hits": [ { ... "_source": { "first_name": "John", "last_name": "Smith", "age": 25, "about": "I love to go rock climbing", "interests": [ "sports", "music" ] } },
![Page 30: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/30.jpg)
ElasticSearch + Doctrine
- Entity se nemapují 1:1 na typy- Typy mají vlastní serializery- V serializerech můžu pokládat SQL dotazy- Synchronizace běží v RabbitMQ workeru
![Page 31: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/31.jpg)
ElasticSearch + Doctrine
$product = $em->find(Product::class, 1);$product->name = 'Banán';$em->flush();
// volá se automaticky$searchSync->append($product);
![Page 32: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/32.jpg)
ElasticSearch + Doctrine
![Page 33: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/33.jpg)
ElasticSearch + Doctrineclass ProductSerializer{ public function serialize($product)
{ return [ 'id' => $product->id, 'name' => $product->name, ]; }
![Page 34: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/34.jpg)
ElasticSearch + Doctrine$query = (new Query(...))
->andMust(...);
$resultSet = $searchManager->search($query);
$products = $productsMapper->mapResult($resultSet);
![Page 35: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/35.jpg)
ElasticSearch + Doctrinefunction mapResult(ResultSet $resultSet){
$result = [];
foreach ($resultSet->results as $item) {$result[$item->id] =
new ProductDTO($item->id, $item->source);}
return $result;}
![Page 36: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/36.jpg)
ElasticSearch + Doctrineclass ProductDTO{
private $id;private $source;
public function __construct($id, $source){
$this->id = $id;$this->source = $source;
}
![Page 37: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/37.jpg)
ElasticSearch + Doctrineclass ProductDTO{
// ...
public function __get($field){
return $this->source[$field];}
![Page 38: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/38.jpg)
Command Query
Responsibility Segregation
![Page 39: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/39.jpg)
CQS
It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both.In other words, Asking a question should not change the answer.
via https://en.wikipedia.org/wiki/Command%E2%80%93query_separation
![Page 40: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/40.jpg)
CQRS
Applies the CQS principle by using separate Query and Command objects to retrieve and modify data, respectively.
via https://en.wikipedia.org/wiki/Command%E2%80%93query_separation
![Page 41: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/41.jpg)
CQRS
- lepší škálování- větší komplexita- častěji je snažší použít CRUD
![Page 42: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/42.jpg)
Shrnutí
- ORM je super- S ORM je jednodušší se střelit do nohy- ElasticSearch je super- CQRS je super
![Page 43: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/43.jpg)
Dotazy?
![Page 44: CQRS v rohlik.cz](https://reader031.vdocuments.pub/reader031/viewer/2022021920/58cffcc11a28abfc0a8b5ba3/html5/thumbnails/44.jpg)
Díky za pozornost!@ProchazkaFilip / @PecemeRohlik