<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Anastasiia Lysenko</title>
    <description>The latest articles on Forem by Anastasiia Lysenko (@soulwife).</description>
    <link>https://forem.com/soulwife</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F397879%2Fd3492cab-396f-4d04-8013-c7d771fe4634.jpeg</url>
      <title>Forem: Anastasiia Lysenko</title>
      <link>https://forem.com/soulwife</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/soulwife"/>
    <language>en</language>
    <item>
      <title>Cutting Edge: Using PHP 8.0 in Enterprise</title>
      <dc:creator>Anastasiia Lysenko</dc:creator>
      <pubDate>Fri, 26 Feb 2021 10:53:45 +0000</pubDate>
      <link>https://forem.com/soulwife/cutting-edge-using-php-8-0-in-enterprise-1535</link>
      <guid>https://forem.com/soulwife/cutting-edge-using-php-8-0-in-enterprise-1535</guid>
      <description>&lt;p&gt;In this article I am planning to describe perks and features of PHP 8.0, that we are already using or going to use in the one of our new microservices in existing chatbot messaging project. &lt;/p&gt;

&lt;p&gt;As many of PHP developers, my team can't wait to try new version of PHP as soon as possible. So, right in time when new microservice got from strategy planning stage to solution architecture choices, I already knew what it's going to be. Long story short, Symfony 5 and PHP 8.0 were the winners. Here I should mention, that we use microservices coupled with DDD business principles and Onion architecture in almost each of them. &lt;a href="https://dev.to/soulwife/real-life-ddd-in-an-onionshell-3ohb"&gt;Here&lt;/a&gt; you can dive in. This strong decoupling made this 'on edge move' possible in such short time.&lt;/p&gt;

&lt;p&gt;Meanwhile, what we like and use from the new features: &lt;/p&gt;

&lt;h1&gt;
  
  
  Duplicated Properties Are Dead! Long Live The Constructor
&lt;/h1&gt;

&lt;p&gt;We all have so many Value Objects and Entities. And each of them looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftyn6xqth3kzqr9f2myb1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftyn6xqth3kzqr9f2myb1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PHP 8.0 and Nikita Popov gave us freedom from properties boilerplate for all simple cases, when you set your properties in constructor:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz20m05a55rajbe8v7msj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz20m05a55rajbe8v7msj.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice and easy. We use it with all our new value objects and entities, as well as other resembling classes.&lt;br&gt;
Be careful: those properties are not allowed in abstract classes and interfaces as well as callable and nullable properties. Surely, you can't declare them twice: as properties and in constructor. &lt;/p&gt;

&lt;h1&gt;
  
  
  Let's make a Union with Types
&lt;/h1&gt;

&lt;p&gt;It's definitely the blast! I personally voted for them, because it's such a strong adding to 'typed properties' from the one side and flexibility from the other. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9q2uwd29unuwlgo1hh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9q2uwd29unuwlgo1hh2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Either you need different types of a number, string, arrays or interfaces: you can now describe all of possible types as input parameters in your methods, class variables and method return. This way you enforce types, so mistakes can be caught early, types are checked during inheritance, enforcing the Liskov Substitution Principle (L from SOLID). You can freely use Reflection, because union types are available through Reflection. The last, but not least, the syntax needs less amount of efforts, than phpdoc.&lt;/p&gt;

&lt;p&gt;So, the question is: what types can't we have as 'union typed'. The following list would be the answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;void&lt;/em&gt; type could not be part of a union, as void means that a function does not return any value.&lt;/li&gt;
&lt;li&gt;The nullable type notation (&lt;em&gt;?Type&lt;/em&gt;) is allowed, so we can do &lt;em&gt;Type|null&lt;/em&gt;, but we are not allowed to include the &lt;em&gt;?Type&lt;/em&gt; notation in union types (&lt;em&gt;?Type1|Type2&lt;/em&gt; is not allowed and we should use &lt;em&gt;Type1|Type2|null&lt;/em&gt; instead).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As many internal functions include &lt;code&gt;false&lt;/code&gt; among the return types, the &lt;code&gt;false&lt;/code&gt; pseudo-type is also supported for backward compatibility.&lt;br&gt;
That capability was only added to support legacy code. So, we are not planning to use it for any new code, so should not anyone.&lt;/p&gt;

&lt;h1&gt;
  
  
  ValueError Exception
&lt;/h1&gt;

&lt;p&gt;From now on we can catch even more bugs on early stages. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zgox8ulse87sesaseat.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zgox8ulse87sesaseat.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;$emptyArray&lt;/code&gt; will be empty, that you have ValueError Exception, that extends Exception:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j64kllznp5gjlabvr0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j64kllznp5gjlabvr0m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PHP throws this exception every time you pass a value to a function, which has a valid type, but can not be used for the particular operation (for example, empty arrays, negative number in case with &lt;code&gt;json_decode&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;p&gt;Sure, we will not catch this specific Error each time, but before PHP 8, all those wrong cases throws just a warning, so it was not possible to catch it with Exception, as it is now. &lt;/p&gt;

&lt;h1&gt;
  
  
  Say hello to &lt;code&gt;Throw&lt;/code&gt; as an expression
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpoftrjxi1ucg5xkx9g6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpoftrjxi1ucg5xkx9g6p.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we can have more readable 'possibly wrong' code with even less amount of 'exception handling' code.&lt;/p&gt;

&lt;p&gt;For those of you, who does not need en $exception as variable in catch block, it's now possible to not define it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewrkfedo4n2r5xvfr6al.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewrkfedo4n2r5xvfr6al.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  String it
&lt;/h1&gt;

&lt;p&gt;PHP 8 gives us a &lt;code&gt;Stringable&lt;/code&gt; interface that corresponds to an object having the __toString() magic method.&lt;/p&gt;

&lt;p&gt;A class may implement a Stringable interface that defines a method public function __toString(): string. Useful fact: if it doesn’t, but still implements that method, the engine will add the method and return type automatically. So, we can now check type in the union type, for example, like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zv3q6ktfu56lhvxdi4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zv3q6ktfu56lhvxdi4h.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Static in return
&lt;/h1&gt;

&lt;p&gt;Many of us get into the situations, when we need to call class methods in chain and get the result from the last one, for example. All those years of JS jokes saying out loud at last gives us chained methods with late static binding from now on. Self, parent and static can now be used in different usecases with chained methods.&lt;/p&gt;

&lt;h1&gt;
  
  
  Do not mix with mixed
&lt;/h1&gt;

&lt;p&gt;From 8.0 you can do this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0rd9a0hbfqa7pidsqbl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0rd9a0hbfqa7pidsqbl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe, it's necessary in some rare cases, but even those cases we refactored to union types in our project. Try to avoid this 'type' as much as possible. Personally, I think it's equal to 'no type at all'. &lt;/p&gt;

&lt;h1&gt;
  
  
  Safe and sound with null
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplud8e2jcv3erniq6gx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplud8e2jcv3erniq6gx0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Personally, one of my favorites. No more &lt;code&gt;if&lt;/code&gt; or strange looking chains with null coalescence operators.&lt;/p&gt;

&lt;h1&gt;
  
  
  We have a match!
&lt;/h1&gt;

&lt;p&gt;And my second favorite is &lt;code&gt;match&lt;/code&gt;. It is pretty similar to well-known &lt;code&gt;switch&lt;/code&gt; but with safer semantics and allowing to return values. So you don't need the variable for it anymore.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Der Teufel steckt im Detail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While &lt;code&gt;switch&lt;/code&gt; compares values loosely (==) potentially leading to unexpected results, match comparison is an identity check (===). I think, it's a huge difference and we are definitely will use &lt;code&gt;match&lt;/code&gt; instead of &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4b5v0ayu7shbrbvwf4la.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4b5v0ayu7shbrbvwf4la.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;match&lt;/code&gt; may also contain multiple comma-separated expressions, that give us opportunity to have more shortened syntax:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69xqb1n6gsva2k7i0ux2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69xqb1n6gsva2k7i0ux2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  More functions, we need more functions
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;str_contains&lt;/code&gt; will definitely come in handy for almost all of us.  &lt;/p&gt;

&lt;p&gt;Say 'no' to every PHP developer nightmare with looking for a match in string. Everytime it's &lt;code&gt;strstr&lt;/code&gt; combined with &lt;code&gt;strpos&lt;/code&gt; and checking to &lt;code&gt;bigger than zero&lt;/code&gt;. Say 'yes' to one simple function instead of it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntw8ax68u9q4ixyx7wxd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntw8ax68u9q4ixyx7wxd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;str_starts_with()&lt;/code&gt; and &lt;code&gt;str_ends_with()&lt;/code&gt; are here for you if you need even more precise search.&lt;/p&gt;

&lt;h1&gt;
  
  
  You name it
&lt;/h1&gt;

&lt;p&gt;I see the main advantage of named arguments is that they allow to specify only arguments we want to change. So it's not necessary to specify default arguments if we don’t want to overwrite default values. The following example makes it clear:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0m4pd9w9sv3j8zn7umf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0m4pd9w9sv3j8zn7umf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Sugar, baby
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;$object::class&lt;/code&gt; is a new &lt;code&gt;get_class()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to Nikita Popov, now instead of remembering another internal function, we can just get the class for an object as simple as that &lt;code&gt;::class&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;What we are definitely planning to use &lt;a href="https://www.php.net/manual/ru/language.attributes.overview.php" rel="noopener noreferrer"&gt;attributes&lt;/a&gt;. As for well-known new feature JIT, I do not see the extreme necessary or gaining some big value for our project in using it at the moment. We have &lt;code&gt;opcache&lt;/code&gt; enabled, as it is by default and using Go for sockets, long time parsers, etc. But, who knows, maybe we'll try it later.&lt;/p&gt;

&lt;p&gt;As conclusion, I should say, that PHP 8.0 got awesome changes and my team and I are so excited to try it in a real live project. We hope, that our code transforms to more clean and readable shape as well as gains performance and usability. &lt;/p&gt;

&lt;p&gt;Time to try it by yourself :)&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Keep your code clean and clear and yourself safe and sound!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>php</category>
      <category>codequality</category>
      <category>codestyle</category>
    </item>
    <item>
      <title>How to handle Stripe?</title>
      <dc:creator>Anastasiia Lysenko</dc:creator>
      <pubDate>Mon, 25 Jan 2021 13:46:30 +0000</pubDate>
      <link>https://forem.com/soulwife/how-to-handle-a-stripe-252l</link>
      <guid>https://forem.com/soulwife/how-to-handle-a-stripe-252l</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is the second one of my 'HowTo:Stripe' series. Set of articles will be helpful for those of managers or developers, who are planning to use &lt;a href="https://stripe.com/"&gt;Stripe&lt;/a&gt; as a payment system or those of you, who already using it. I won't compare Stripe with analogs (let's just say, &lt;a href="https://www.braintreepayments.com/"&gt;BrainTree&lt;/a&gt; is also a great fit for this purpose), but rather planning to provide a detailed instruction on how to implement a ready-and-working one-time checkout or subscription system with billing cycle of recurrent payments.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If you are already have answers on questions from the &lt;a href="https://dev.to/soulwife/pay-or-not-to-pay-with-stripe-subscriptions-from-zero-to-cycling-14l0"&gt;previous article&lt;/a&gt;, you are all-set to begin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Game On
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rttC0DrZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6igz6pnkw5zu1wtzg0he.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rttC0DrZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6igz6pnkw5zu1wtzg0he.jpg" alt="Alt Text" width="880" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Stripe game, any payment begins with creating Customer and Checkout Session for this Customer in Stripe (&lt;a href="https://stripe.com/docs/billing/subscriptions/checkout#create-session"&gt;here the details how to do it&lt;/a&gt;). The moment we create those Entities in Stripe, we need to create our &lt;code&gt;StripeCustomer&lt;/code&gt; and &lt;strong&gt;&lt;code&gt;StripeCheckoutSession&lt;/code&gt;&lt;/strong&gt; accordingly with necessary data, that Stripe gave to us (identifiers, dates, so on). &lt;br&gt;
&lt;strong&gt;&lt;code&gt;StripeCustomer&lt;/code&gt;&lt;/strong&gt;: I recommend to save only necessary data here (for example, stripe customer id, createdAtStripe datetime and customer email) and link it One-to-One with your User identity via userId field.&lt;br&gt;
&lt;strong&gt;&lt;code&gt;StripeCheckoutSession&lt;/code&gt;&lt;/strong&gt;: the best here is to save such data, as stripe session identifier, created and updated datetime and stripe customer identifier (Many-to-One with Customer here). In case you have a Subscription type checkout, there are two more fields, that are necessary here: &lt;code&gt;subscriptionId&lt;/code&gt; (stripe subscription identifier, null at this moment) and &lt;code&gt;product identifier&lt;/code&gt; (your 'subscription' identifier). &lt;/p&gt;

&lt;p&gt;Important to know, that Session is always should be linked with your 'product' specification in order to control and respond to any stripe changes and save this 'product identifier' in &lt;code&gt;StripeSubscription&lt;/code&gt; later on accordingly with Stripe Checkout Process and webhooks. Those 'Customer-CheckoutSession' actions should be handled by one &lt;code&gt;CreateStripeCheckoutSession&lt;/code&gt; query. So, you can return 'ready-to-pay' Session object to the Web Client in response on &lt;code&gt;CreateStripeCheckoutSession&lt;/code&gt; query. Note, that if you do not want to create a customer for every checkout session (every payment), you need to pass it to Stripe at the moment you create a CheckoutSession in Stripe. Our &lt;code&gt;StripeCustomer&lt;/code&gt; linked with User comes in handy here: you can just look by your user identity identifier among all customers in your &lt;code&gt;StripeCustomer&lt;/code&gt; table and use it after that.&lt;/p&gt;

&lt;p&gt;One should not forget to setup 'keys': Stripe gives you public and private keys. The first one you are going to use in frontend queries and the second one should be set in any API query to Stripe from backend. You can find your keys at your project 'Dashboard' main page.&lt;/p&gt;

&lt;p&gt;Now the client can proceed with payment and actually pay for your product in a one-time-checkout or subscribe to the billing cycle. &lt;/p&gt;
&lt;h2&gt;
  
  
  Take it all
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dJxvBAG3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8fjk9dymlvq6mxulf9n3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dJxvBAG3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8fjk9dymlvq6mxulf9n3.png" alt="Alt Text" width="880" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The client is going to be redirected to the &lt;code&gt;success_url&lt;/code&gt;, that you set up when initiated the Checkout Session, in case of successful checkout and to &lt;code&gt;cancel_url&lt;/code&gt; page otherwise. If you have the one-time-checkout, than I have good news for you: it's almost done. You need to update the status of your checkout session in order to know, that everything paid in &lt;a href="https://stripe.com/docs/payments/accept-a-payment?integration=elements#add-an-event-handler-to-the-checkout-button"&gt;&lt;code&gt;redirectToCheckout&lt;/code&gt;&lt;/a&gt; event handler and that's all. &lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;del&gt;#FollowMe&lt;/del&gt; #SubscribeMe
&lt;/h2&gt;

&lt;p&gt;Meanwhile, with 'Subscription' type of payment, we are not done here. During the payment and redirect process, you need to receive and handle all necessary webhooks in order to show 'paid' invoices and 'active' subscription in his success page.&lt;/p&gt;

&lt;p&gt;It means, that you are going to need a full cycle of recurrent payments. So, you have to operate with the next types of event entities:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stripe.com/docs/api/subscriptions/object"&gt;Subscription&lt;/a&gt;,&lt;br&gt;
&lt;a href="https://stripe.com/docs/api/checkout/sessions/object"&gt;Checkout Session&lt;/a&gt;,&lt;br&gt;
&lt;a href="https://stripe.com/docs/api/customers/object"&gt;Customer&lt;/a&gt;,&lt;br&gt;
&lt;a href="https://stripe.com/docs/api/invoices/object"&gt;Invoice&lt;/a&gt;,&lt;br&gt;
&lt;a href="https://stripe.com/docs/api/events/types#charge_object"&gt;Charge&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All those entities have required and not required fields. Some of entity fields can be absent during specific event, but filled out in other. For example, &lt;code&gt;subscription&lt;/code&gt; or &lt;code&gt;pdf&lt;/code&gt; fields are absent during &lt;code&gt;invoice.created&lt;/code&gt; or any other &lt;code&gt;invoice&lt;/code&gt; event, which happens before &lt;code&gt;subscription.created&lt;/code&gt; and so on. All event fields you can find in specific &lt;a href=""&gt;StripeEventInputType article (TBD)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, in order to receive all important events, you need to listen to at least the following event list:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--urKYO0CA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k6aa6wd2d6pp1go6iuya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--urKYO0CA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k6aa6wd2d6pp1go6iuya.png" alt="Alt Text" width="426" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can setup whatever stack you have as listener and create a &lt;code&gt;Webhook point&lt;/code&gt; at &lt;a href="https://dashboard.stripe.com/account/webhooks"&gt;your dashboard&lt;/a&gt;. Do not forget, that you should always listen to webhooks. Important to notice, that here you should check signature, that Stripe gave you as 'Signing Secret' on Webhhoks page. Do it for every query, that you receive. &lt;/p&gt;

&lt;p&gt;All events, that come from Stripe, go directly to this Webhook point. Here you can respond directly or format it depending on the event type and send to your API to handle.  Here, not dependently on event type, I recommend to save any of it as &lt;code&gt;StripeEvent&lt;/code&gt; and respond to event accordingly with it's type only after that. Having it that way, you can always find all events, that you received from Stripe at any time by 'customerId' in your &lt;code&gt;StripeEvent&lt;/code&gt; table or you can setup a view in your admin panel as well.&lt;/p&gt;

&lt;p&gt;Here we come to the most not obvious and crazy thing, that I have not expected from a fancy world-wide-known system. Stripe send all webhooks asynchronously. So you can never know you can never know what comes first: subscription, invoice or checkout session webhook. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dmTRERc7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p9oaalffyi8b3wmcwncg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dmTRERc7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p9oaalffyi8b3wmcwncg.png" alt="Alt Text" width="266" height="96"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is that not convenient at all? At first, all data, that can be linked with is 'checkout session' for specific payment and 'customer' for user in general. &lt;br&gt;
But the thing is 'checkout.completed' webhook you can receive at any time: after &lt;code&gt;invoice.finalized&lt;/code&gt; or &lt;code&gt;subscription.created&lt;/code&gt;. More to that, you can give &lt;code&gt;invoice.finalized&lt;/code&gt; before &lt;code&gt;invoice.created&lt;/code&gt; and so on with invoices. More to it, you can get 'subscription' at the end of webhooks list. In that way, you firstly getting an invoice, that you can save, but you can't attach it to subscription, because there are none at the moment and you can't attach it to your 'product' (e.g. subscription plan), because you can't identify the specific product in your DB with paid invoice. Sure thing, in order to deal with asynchronous Stripe events we got all cases handled. I am going to describe it in detail in the next article in this series. In a nutshell, the most important thing is to save and link Stripe subscription with invoices, checkout session with subscription and subscription with your product. Every event should be handled by different Handler, for example, it can look in the following way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HandleStripeChargeWebhookSrevice
HandleStripeInvoiceWebhookService
HandleStripeCheckoutWebhookService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...&lt;br&gt;
so on.&lt;/p&gt;

&lt;p&gt;Useful Stripe Docs, that comes in handy:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stripe.com/docs/webhooks"&gt;Webhooks&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stripe.com/docs/api/events/types"&gt;Event types&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stripe.com/docs/billing/subscriptions/overview"&gt;Subscriptions&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stripe.com/docs/testing"&gt;Cards to test billing&lt;/a&gt;&lt;br&gt;
&lt;a href="https://stripe.com/docs/stripe-cli"&gt;Stripe CLI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In the next article I am going to specify ways to handle 'asynchronous' webhooks and how each event may look like.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Keep your code clean and yourself safe and sound.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>stripe</category>
      <category>webdev</category>
      <category>howto</category>
      <category>payment</category>
    </item>
    <item>
      <title>To pay or not to pay with Stripe: subscriptions from 'zero' to 'cycling'</title>
      <dc:creator>Anastasiia Lysenko</dc:creator>
      <pubDate>Mon, 25 Jan 2021 13:26:06 +0000</pubDate>
      <link>https://forem.com/soulwife/pay-or-not-to-pay-with-stripe-subscriptions-from-zero-to-cycling-14l0</link>
      <guid>https://forem.com/soulwife/pay-or-not-to-pay-with-stripe-subscriptions-from-zero-to-cycling-14l0</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is the first one of my 'HowTo:Stripe' series. Set of articles will be helpful for those of managers or developers, who are planning to use &lt;a href="https://stripe.com/"&gt;Stripe&lt;/a&gt; as a payment system or those of you, who are already using it. I won't compare Stripe with analogs (let's just say, &lt;a href="https://www.braintreepayments.com/"&gt;BrainTree&lt;/a&gt; is also a great fit for this purpose), but rather planning to provide a detailed instruction on how to implement a ready-and-working one-time checkout or subscription system with billing cycles.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;As you may already know, Stripe has a great API. And I must say, that from my experience, it's totally true! In addition to that, there are a CLI for your needs, that also comes in handy, especially for testing purposes or if you have to register your 'products' dynamically. They even have a docker image with it inside. The &lt;a href="https://stripe.com/docs/stripe-cli"&gt;documentation&lt;/a&gt; tells anyone everything one need to know.&lt;/p&gt;

&lt;p&gt;Anyway, before you can set up your project payments via Stripe, you need to have answers on the following questions:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Is it going to be a 'one-time' payment or subscription?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KM2W0CED--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8trp2u4l1qt9xriivc7c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KM2W0CED--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8trp2u4l1qt9xriivc7c.png" alt="Alt Text" width="880" height="586"&gt;&lt;/a&gt;&lt;br&gt;
In the first case, you just need to create a 'Product' and you set and go with &lt;a href="https://stripe.com/docs/payments/accept-a-payment?integration=checkout"&gt;One-Time-Checkout&lt;/a&gt;. The 'Product' is like an item to sell, but in more general way: newspaper subscription, business plan, set of plates are all 'Products' in the terms of the  scope of Stripe. Meanwhile, in the last case you are going to need much more to work on. Anyway, you can find instructions on how to operate in both cases below.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Is amount of your 'items-to-be-paid-for' going to be a not very big and static value?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KYY7USCQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/15uhvkj5ynbbzar3yyxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KYY7USCQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/15uhvkj5ynbbzar3yyxt.png" alt="Alt Text" width="880" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why it is so important to know at the early stage of implementation? Because, there are a bad news for you in case you have a whole bunch of, let's just say, clothes with unique prices for each of them. In this case you need to clone payment details for every product in your store system in Stripe. More to it, it's necessary to do it twice: in the testing environment and in production. So, the flow for each new t-shirt will be the following: create it in your store ➡️ create it on stand ➡️ create it on production environment. Sure thing, you can do this via API query, but anyway it's time and code. The full picture looks different in the other case your 'Products' are 'subscriptions'. Also it's very convenient solution in case of not big and rarely changeable amount of items to sell.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;What's a default currency for your merchant?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---SDMIKK8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gcunaz8xx9jjhsinc3f9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---SDMIKK8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gcunaz8xx9jjhsinc3f9.png" alt="Alt Text" width="880" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can create a Product with just one for all countries currency, that will be automatically converted for most of the countries. You can find more about automated currency conversion and fees for it &lt;a href="https://stripe.com/docs/connect/currencies"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Are you ready to have only one test stage and the same team working on test and live panel?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--znq3SGDT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1a0fqcgebhwrv21ahg9w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--znq3SGDT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1a0fqcgebhwrv21ahg9w.jpg" alt="Alt Text" width="259" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite of different Products and Webhooks setup, they really have only one team to manage Stripe at web panel. The list of Roles are also not so wide: only six of them and only two of them has 'read' access to Webhooks section, but along with it those users are going to have 'write' access to customers, subscriptions and so on. So, important to know: your 'Developers' are going to have broad list of possibilities on production environments. The full list is &lt;a href="https://stripe.com/docs/dashboard/teams"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If at this point you define Stripe as a fit, that fulfill your purposes, then you need to go to your &lt;a href="https://dashboard.stripe.com/"&gt;Stripe Dashboard&lt;/a&gt; and setup your Stripe system with a branding, team and products.&lt;/p&gt;

&lt;p&gt;On initial setup, you can leave all settings as they are, but you are definitely have to create a 'Product' and a 'Price' with default currency for each product. If it's a Subscription, then you need to choose a 'Billing cycle'. 'Billing cycle' and currency are customizable here. By default, it's 'month/half of year/year' as billing cycle and 'usd' as default currency.&lt;/p&gt;

&lt;p&gt;The next &lt;a href="https://dev.to/soulwife/how-to-handle-a-stripe-252l"&gt;article&lt;/a&gt; is ready for you on this Stripe journey.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Keep your code clean and yourself safe and sound.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>stripe</category>
      <category>merchant</category>
      <category>howto</category>
    </item>
    <item>
      <title>GraphQL: Files, upload more files!</title>
      <dc:creator>Anastasiia Lysenko</dc:creator>
      <pubDate>Wed, 06 Jan 2021 07:56:09 +0000</pubDate>
      <link>https://forem.com/soulwife/graphql-files-we-need-more-files-3cja</link>
      <guid>https://forem.com/soulwife/graphql-files-we-need-more-files-3cja</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is a part of my 'graphql' articles series, so be free to check out other as well in case you are interested in 'three years long graphql adventure in real-life projects'.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Well, what is the one of the most needed and wide-use web features? Surely, it is file upload.&lt;br&gt;
Pff, what’s a fuss, you may think of. Standard &lt;code&gt;multipart/form-data&lt;/code&gt;, &lt;code&gt;FILES&lt;/code&gt; array|&lt;code&gt;FileInputStream&lt;/code&gt;|etc., attach validation and dunk. Various implementations in all kinds of languages, frameworks or vendors. At this moment you are possibly thinking and what's wrong with GraphQL, why can we implement it as usual? You can! And nothing will stop you from doing it the standard way. Well, wait, except, one thing. If you upload files via from an PHP Files array (or any other backend language solution), your query handler (resolver) will know literally nothing about the uploaded files. It’s simply a query without files in it. You are going to handle it as usual, but on the Application layer: obtain  the file structure and work with it. We have this type of uploading on my first DDD with GraphQL project and it has nothing good with it. To mix layers logic is always a bad decision in any project architecture. It was no good then and I always want to change that and know that in any project from scratch I’ll do the right thing. And in the current project it has been successfully implemented by me and my fellow teammates.&lt;/p&gt;



&lt;p&gt;GraphQL enthusiasts and developers have ready and working solution for you. Let’s meet an &lt;strong&gt;UploadType&lt;/strong&gt; - the custom type for uploaded files, that has been implemented by &lt;a href="https://github.com/Ecodev/graphql-upload"&gt;Ecodev&lt;/a&gt; developers. &lt;br&gt;
Arguments, and as to be more specific, one parameter to load file with this type looks pretty simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FileUploaderResolver:

'args' =&amp;gt; [ 'file' =&amp;gt; new UploadType()]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FileUpload Mutation Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mutation(
   $file: Upload
) {
   uploadYourFileHere(
       file: $file
   ) {
      File {
          path,        
          name
      }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More to say, after you create a resolver and use this object type in it, your additional application logic actions with this file will be identical to the version with standard file uploading. Frontend developers should download a file and send it in &lt;code&gt;map&lt;/code&gt; schema. &lt;/p&gt;

&lt;p&gt;For example, request payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="operations"

{ "query": "mutation ($file: Upload!) { uploadYourFileHere(file: $file) { id } }", "variables": { "file": null } }
--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="map"

{ "0": ["variables.file"] }
--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="0"; filename="a.txt"
Content-Type: text/plain
Alpha file content.

--------------------------cec8e8123c05ba25--
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And list of files (difference will be only in 'map' here and List(Upload) as mutation param accordingly):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Content-Disposition: form-data; name="map"

{ "0": ["variables.files.0"], "1": ["variables.files.1"] }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can explore all the details in the &lt;a href="https://github.com/jaydenseric/graphql-multipart-request-spec"&gt;GraphQl Multipart Request documentation&lt;/a&gt; or in &lt;a href="https://github.com/Ecodev/graphql-upload/blob/master/tests/UploadMiddlewareTest.php"&gt;tests&lt;/a&gt; in the Ecodev library. &lt;/p&gt;

&lt;p&gt;After uploading, you can store files in any preferable way. As Cloud adept, I prefer to store them in AWS S3 with links in DB.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep your code clean and yourself safe and sound.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>fileupload</category>
      <category>howto</category>
    </item>
    <item>
      <title>GraphQL: change for the best</title>
      <dc:creator>Anastasiia Lysenko</dc:creator>
      <pubDate>Thu, 10 Dec 2020 15:58:38 +0000</pubDate>
      <link>https://forem.com/soulwife/graphql-change-for-the-best-4pf6</link>
      <guid>https://forem.com/soulwife/graphql-change-for-the-best-4pf6</guid>
      <description>&lt;p&gt;Today I’d like to share with you real-life code and schema example how one can successfully integrate GraphQL into PHP and how to optimize the result. At the moment it’s hardly unlikely to meet web-developer, who doesn’t know or doesn’t hear  a thing  about GraphQL. And it’s understandable: more and more developers choose to begin or continue to use it in their projects due to various advantages. Such as single end-point, extendable hierarchy, strict types, flexibility among others.&lt;br&gt;
Despite the well-known fact that we are living and developing in the stackoverflow and medium era, each of us is constantly stuck with a ‘can not be googled’ type of task once in a while.  Usually it happens when you want or should to create something big or try the new approach and in those cases you need as much information as one can get. The documentation always comes in handy in those cases and one begins with deep dive into it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs6f6qvag6v6hiip5riij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs6f6qvag6v6hiip5riij.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This step is totally where you got covered with any type of information from the official site. But theory is cheap, you are not going to be getting paid for it, right? So, on the next step, that includes taking off pink glasses and turning theory into a practice, you are totally limited by project language or framework. Today I’d like to present a solution for using GraphQL with PHP as a server side language. You are not going to hear a detailed explanation of a GraphQL documentation or PHP ports for GraphQL. What you will definitely get in detail is an example of an GraphQL integration into a PHP project, like one you can see on your screen.  I mean, if someone had provided me the full example of an enterprise project three years ago, I would be more than happy. But no, it was not gonna happen then, but now I have one for you. More to it, I’m going to describe how you can solve the most common issues that you are most likely to get into and the most working ways to optimize queries. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd2izv0b70takxm6kt4gh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd2izv0b70takxm6kt4gh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firstly, you should choose a GraphQL port that you’ll be working with. To fulfill that purpose, one can simply open the official GraphQL site and look for the PHP section in it. You’ll see a short list with three general-use libraries and a few of framework-use. I am actively using the first one from the &lt;a href="https://github.com/webonyx/graphql-php" rel="noopener noreferrer"&gt;WebOnyx&lt;/a&gt; for about three years for now and don’t have any major issues for now. They have a bit specific error handling as for me, but we solved this with a custom error handler. &lt;br&gt;
In addition to the vendor library, you’ll most likely be in need for the schema &lt;a href="https://github.com/2fd/graphdoc" rel="noopener noreferrer"&gt;documentation generator&lt;/a&gt;. This one seems to be a perfect fit for all GraphQL projects that I’ve worked with. It’s simple in use and setup and your schemes will be always up to date (while you run on deploy the specific command for it, of course).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3ec54zn0vivc2csr4ij9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3ec54zn0vivc2csr4ij9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Meanwhile, for a ready and working GraphQL API you’ll need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To design and to build request and response resolvers, design and handle schemes and data view models&lt;/li&gt;
&lt;li&gt;Choose the most fitting pagination invariant and integrate it in code&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;ResultHandler&lt;/code&gt; and an &lt;code&gt;ErrorHandler&lt;/code&gt; (it’s nothing easy in this world)&lt;/li&gt;
&lt;li&gt;Create endpoint&lt;/li&gt;
&lt;li&gt;Send a query&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s review each step in detail:&lt;/p&gt;

&lt;p&gt;Well, let’s assume you have a GraphQL request parameters and know what response it should return in its body. So now you should resolve this specific request into a specific response. The main tasks of any Resolver are “query a request” and 'return a response', that’s why it has only four methods: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;query&lt;/code&gt; Here you can wrap parent vendor query method with necessary redefining of ‘resolve’ param) &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createRequest&lt;/code&gt; In this method we can shape the request, that we have from the endpoint by adding query variables and query body as separate data attributes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createResponse&lt;/code&gt; The perfect method for initializing assemblers for the usecases (as analogy, I can describe it with calling application service). Use case in general in DDD is an Application Service. But besides it we additionally have to integrate the middle-ware layer (application validation check, do authorization check, data access check, etc.) and initialize Use Case with data. In general, we need to assemble query data into Use Case and return response from it. So, I call it &lt;code&gt;UseCaseAssembler&lt;/code&gt;. You can read about DDD and it's live project implementation &lt;a href="https://dev.to/soulwife/real-life-ddd-in-an-onionshell-3ohb"&gt;here&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;and the last method is an abstract method &lt;code&gt;response&lt;/code&gt; that needs to be implemented in each specific Resolver.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well, to get a better understanding, we can get a look into specific query example. Well, you have an entity Wishlist, an object of which you need to create. Creation query may look exactly like on your screens. Each query contains fields of two types: type and arguments. The type tells us that we are going to get a Wishlist interface and structured data in response as a result. And the second field type is ‘arguments’, where you obviously have the set of input variables. You can always get a good look into input variables types on the official GraphQL site or WebOnyx as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolver
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhr0ep0b0q2b66cel1mcg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhr0ep0b0q2b66cel1mcg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CreateWishlistResolver.php
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm7eawfo385wfqfkzvjsk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm7eawfo385wfqfkzvjsk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Wishlist&lt;/code&gt; schema may look like that one. Any schema should have an interface and object that implements it. So, there are Wishlist interface and Wishlist object. The various output GraphQL types are always there: on the &lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;official site&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  WishlistSchema.php
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyk9a4wznigra7buynndl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyk9a4wznigra7buynndl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If GraphQL adepts talking about pagination, there is always a war. The infinite war between two clans: the first one is 'Cursor' and the second one is 'Offset'. In truth, as usual with almost all wars sides, they have not so many differences in schema. The main difference will be at looking up in persistent storage. 'Cursor' charter looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsgs89q19nmm5m7hnnszb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsgs89q19nmm5m7hnnszb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Meanwhile, there is a light at the end of a tunnel. If you roll a dice and choose a pagination side, you should create a &lt;code&gt;PageInfo&lt;/code&gt; schema class (it looks exactly like &lt;code&gt;WishlistSchema&lt;/code&gt;, that you saw before). And… understand, that method render is not gonna help us anymore, just because it fits only one data record and doesn’t have pagination in it. So, that’s a moment when you understand that you're gonna need two types of response presenters: for one node and another one, that fits the collection of nodes. &lt;/p&gt;

&lt;h3&gt;
  
  
  CollectionPresenter.php
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F62bdpggvy10612tjyg9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F62bdpggvy10612tjyg9u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  NodePresenter.php
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp1zhhcp0rqj3n3zyc9md.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp1zhhcp0rqj3n3zyc9md.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naturally, our frontend developers nicely ask or not so nicely demand 24/7 valid schema and fine-structured handled errors, preferably with error codes in case if something goes wrong. As you can notice from the render methods on previous screens, there is always  a method &lt;code&gt;getResultFields()&lt;/code&gt; in each of the render method. As one can suppose from the method name, it returns the schema of general result fields. Any query result is going to have this schema. In case of any errors it will consist of ‘errors’ set of fields and you work with response respectively to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  AbstractPresenter.php
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg0h5cfi8uv6in32avuo7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg0h5cfi8uv6in32avuo7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result handling schema may look something like you see on display:&lt;/p&gt;

&lt;h3&gt;
  
  
  ResultSchema.php
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5fvagfguz3uusiun0gbb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5fvagfguz3uusiun0gbb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, as I explained earlier, we definitely need to return an error message and code in case of any errors, so whoever gets a response can notice that something went wrong and may handle errors accordingly with their codes. That's how we provide the maximum possible error handling strategy and do not leave any of ‘unpredictable’ for the API user cases as a result. Your frontend engineers will thank you for that, you’ll see. It’s worse to mention, that GraphQL schema errors (like wrong type or absence of required field) are going to be catched and returned by the vendor library, so you can add your own Exception for those  types of errors. It definitely helps you to get human readable exception traces. &lt;/p&gt;

&lt;p&gt;We have two points left from the our conquer GraphQL plan: make an endpoint and send a query.&lt;/p&gt;

&lt;p&gt;To make an endpoint it’s a specific task, I’ll explain how you can possibly do it with our case. Historically, we are using Laravel, so our endpoint is a one and only controller with two methods. The first one is for all GraphQL queries, obviously and the second one &lt;code&gt;graphQLResponse&lt;/code&gt; is about making a PSR7 json Response from the response data of the query.&lt;/p&gt;

&lt;p&gt;Meanwhile, there's only one thing left. We need to actually send a query to the endpoint URL. We are actively using Insomnia and Postman and I can recommend both of them. &lt;/p&gt;

&lt;h3&gt;
  
  
  Controller.php
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F52s78o929l5fvt2mcjs7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F52s78o929l5fvt2mcjs7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Well, congratulations! You can do a full circle of GraphQL query in PHP. &lt;br&gt;
Hope that you have learned some practical or theoretical things that come in handy to those who want to use GraphQL with PHP or already using it. Every cook praises his own broth. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep your code clean and yourself safe and sound.&lt;/em&gt; &lt;/p&gt;

</description>
      <category>graphql</category>
      <category>php</category>
      <category>codeexample</category>
    </item>
    <item>
      <title>CQRS code example "Requested"</title>
      <dc:creator>Anastasiia Lysenko</dc:creator>
      <pubDate>Mon, 30 Nov 2020 14:17:24 +0000</pubDate>
      <link>https://forem.com/soulwife/bounded-context-command-task-requested-29k3</link>
      <guid>https://forem.com/soulwife/bounded-context-command-task-requested-29k3</guid>
      <description>&lt;p&gt;This post is linked with the detailed article &lt;a href="https://dev.to/soulwife/real-life-ddd-in-an-onionshell-3ohb"&gt;Real-life DDD in an "onionshell"&lt;/a&gt; and explains with code examples specific version of a standard CQRS command requests. This customization allows us to handle different types of command requests integrating with bounded contexts. &lt;/p&gt;

&lt;p&gt;Our service has two types of API requests: external "usecase" type and "command request" type, that can be external and internal. The second type can be managed differently, depending on it’s goal. It can be a simple external request to handle a command. Another time it can be a complex task with transaction in it. So we should use a different approach for every version of the task according to the configuration pre-set. Either way we create a task request and manage it using a message broker. &lt;/p&gt;

&lt;p&gt;We have "usecase" and "request-commands" concept. Last one should be used for any server-to-server or context-to-context interaction. &lt;br&gt;
Request command should be created via CommandRunner (RequestCommandHandlerService), that operates with command handlers and have the following interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * Interface CommandRunner
 * @package Utility\RequestCommand
 */
interface CommandRunner
{
    /**
     * @param TaskRequestInterface $taskRequest
     * @throws JsonException
     */
    public function send(TaskRequestInterface $taskRequest): void;

    /**
     * @param TaskRequestInterface $taskRequest
     * @throws CommandRequestException
     */
    public function run(TaskRequestInterface $taskRequest): void;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of handle pairs should be determined in configuration &lt;code&gt;config.php/requestCommand.php&lt;/code&gt;. For example,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0w0aobah86o82cf69c4t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0w0aobah86o82cf69c4t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If request command is going to be called externally you are going to need alias for this call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
|------------------------------------------------------------
| Handlers Aliases
|------------------------------------------------------------
*/
'requestAliases' =&amp;gt; [
    'makeMessage' =&amp;gt; MakeMessageTaskRequest::class,
    'createTeam'  =&amp;gt; CreateTeamTaskRequest::class,
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's way we can add multi-purpose Handler-Request pair to 'requestCommand'. It can be simple peer-to-peer:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AddScenarioStatisticTaskRequest::class =&amp;gt; AddScenarioStatisticHandler::class&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or transaction mode (all handlers are going to be committed in one transaction):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MakeMessageTaskRequest::class =&amp;gt; [
     MakeMessageTaskRequest::class =&amp;gt; MakeMessageHandler::class,
     UpdateSessionLastSeenTaskRequest::class =&amp;gt; UpdateSessionLastSeenHandler::class
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pay attention here: you should create only one request via command handler, for example 'MakeMessageTaskRequest' and all other requests are going to be created automatically according with your chain of requests/handlers. &lt;/p&gt;

&lt;p&gt;After that you can create specific TaskRequest with entity-specific DTO in Infrastructure/TaskRequest and Handler for it in Application/CommandHandler. &lt;br&gt;
TaskRequest example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9tpbksnktt2qipyn7zdt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9tpbksnktt2qipyn7zdt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yep, it's going to be DeactivateUserTariffPlanDTO instead of RequestDTO immediately after we update PHP version to 8.0 :)&lt;/p&gt;

&lt;p&gt;CommandHandler example (it can be in any context):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcmnvi68y97tillo89hex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcmnvi68y97tillo89hex.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, handler 'process' method should call Application Service accordingly with procedure, that you need. Add Middleware Validators for each of them accordingly in Handler.&lt;/p&gt;

&lt;p&gt;Handler without Transactions should implement &lt;code&gt;RequestCommandHandler&lt;/code&gt; interface and Transaction Handlers should implement &lt;code&gt;RequestCommandHandler,TransactionRequestCommandHandler&lt;/code&gt; interfaces.&lt;/p&gt;

&lt;p&gt;There are two types of transaction handlers: "insiders" and "closing". Insiders (implements &lt;code&gt;InsiderTransactionRequestCommandHandler&lt;/code&gt; interface as well) should create DTO for the next transaction request in the &lt;code&gt;process()&lt;/code&gt; method via creating&lt;br&gt;&lt;br&gt;
&lt;code&gt;$this-&amp;gt;nextTransactionRequestDTO&lt;/code&gt; and return it in the following way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * @return bool
 */
public function isInTransaction(): bool
{
    return true;
}

/**
 * @return RequestDTO|null
*/
public function getNextTransactionRequestDTO(): RequestDTO
{
    return $this-&amp;gt;nextTransactionRequestDTO;
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Closing one closes transaction (the last request on the list), so it should only implement &lt;code&gt;isInTransaction&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * @return bool
*/
public function isInTransaction(): bool
{
    return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am planning to create two different strategies for "insiders" and "closing" request, but it haven't done yet.&lt;br&gt;
&lt;code&gt;TaskHandler&lt;/code&gt; is going to handle all inner processes, such as setup transactions decorator service with UnitOfWork, obtain and handle request-commands pairs and request data from the configuration service, handle low-level exceptions and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1kvupvq2ue0h3s8smkk8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1kvupvq2ue0h3s8smkk8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All we have left to do is to start listen "request-command" queue via message broker (we use RabbitMQ, but it's going to work with any of brokers, anyway). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Example for DeactivateUserTariffPlan:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From any of bounded contexts services inside API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$this-&amp;gt;commandRunner-&amp;gt;send(new DeactivateUserTariffPlanTaskRequest(new DeactivateUserTariffPlanDTO(['userId' =&amp;gt; 1])));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From external services (for example, API Gateway):&lt;/p&gt;

&lt;p&gt;Send json data to the "request-command" queue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    'userId' =&amp;gt; 1
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>cqrs</category>
      <category>php</category>
      <category>codeexample</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Real-life Domain Driven Design in an "onionshell"</title>
      <dc:creator>Anastasiia Lysenko</dc:creator>
      <pubDate>Fri, 27 Nov 2020 10:55:06 +0000</pubDate>
      <link>https://forem.com/soulwife/real-life-ddd-in-an-onionshell-3ohb</link>
      <guid>https://forem.com/soulwife/real-life-ddd-in-an-onionshell-3ohb</guid>
      <description>&lt;p&gt;Domain-Driven Design (DDD) gives us the most real-world approach to defining what really has business value. Coupling it with Onion Architecture, we can achieve a good level of layers communication and abstract the technology specifications that are secondary to the business. The best way to explain Domain Storytelling is to see it in action, as well as any architectural pattern (like Onion) can be properly introduced via a clean and clear example. So, I’d like to present a lightweight blueprint that can be used by agile teams as guidance for designing large-scale development programs. Furthermore, it’s been over three years, as I’ve designed, built and maintained two projects using DDD and multi-layered architecture, so you can get your hands on ready-and-working enterprise design schema and code solutions.&lt;/p&gt;

&lt;p&gt;Let’s start with business needs. Nowadays, if we are talking about some complex service solution, it’s always about services. When you have separate services that communicate with each other over the network, you have a distributed system. In these systems, choosing the wrong integration strategy might cause slow or unreliable systems that lead to negative business impacts. That’s why it’s very important for the Architect and Developers to understand the best approaches to building scalable distributed systems.&lt;br&gt;
Having to distribute a system introduces the need to break it up into smaller deployable components. This is a moment where you understand that DDD is a most fitting design and &lt;em&gt;perfect&lt;/em&gt; choice in cases with complex or ‘going-to-be’ complex systems.&lt;/p&gt;

&lt;p&gt;Well, it’s time for the first Schema. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5gjkhijtkbz5w4ev3yk8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5gjkhijtkbz5w4ev3yk8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some of you can recognize the standard &lt;strong&gt;Onion Architecture&lt;/strong&gt; schematic introduced by &lt;a href="https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/" rel="noopener noreferrer"&gt;Jeffrey Palermo in 2008&lt;/a&gt;. The idea of the Onion Architecture is to place the Domain and Application Layers at the center of your application. And the Presentation and Infrastructure layers are located in external circles. The main point of this architecture is data flow direction. From the UI through our Application Service to our Domain Model and back to the outside. It can be compared with cross-cutting the onion, but with dry eyes in this case. It is important to notice that all dependencies move inwards. The layers inside the application core define the interfaces that the outer layers can use. The outer layers thus depend on the inner layers interfaces. &lt;/p&gt;

&lt;p&gt;Onion is an architectural pattern for a system, whereas DDD is a way to design a subset of the objects in the system. Therefore in my practice, Onion architecture is the best among others to be coupled with DDD design and to integrate DDD principles in the real-life projects. Let’s see how we can move from the 2-D flat circle to the 3-D representation. &lt;del&gt;Magically&lt;/del&gt; circle turns to cylinder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4s3gs5x0fn18qezbfgo5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4s3gs5x0fn18qezbfgo5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mapping the implementation model back to the analysis model and ensuring they are bound to one another is hard. To guide developers and clarify designs, Evans has built upon the domain model pattern that was first cataloged in Martin Fowler’s book &lt;a href="https://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420" rel="noopener noreferrer"&gt;Patterns of Enterprise Application Architecture&lt;/a&gt;. Those patterns used to create domain models and tie implementation to analysis have continually evolved since Evans’s original text.&lt;/p&gt;

&lt;p&gt;And today I shall introduce you to my implementation of a highly scalable autonomic distributive API, that effectively adapts DDD patterns with ‘Onion’ architecture. I know, it’s not simple from the first glance, but we’ll get through each layer together step by step and at the end it will be clean and clear. &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;em&gt;Domain Layer&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F04rfoqmgtyxn71m6byzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F04rfoqmgtyxn71m6byzn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
DDD is definitely NOT about technology. DDD is all about the business domain. As Eric Evans defines a domain layer in a project: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This layer is the heart of business software.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me describe domain layer of the enterprise project blueprint in detail: &lt;/p&gt;

&lt;h3&gt;
  
  
  DTO
&lt;/h3&gt;

&lt;p&gt;It's an acronym which stands for Data Transfer Object. Although the main reason for using a Data Transfer Object is to batch up what would be multiple remote calls into a single call, it's worth mentioning that another advantage is to encapsulate all simple request data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exception
&lt;/h3&gt;

&lt;p&gt;Understandably, there we keep exceptions, which we use in a project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repository interfaces
&lt;/h3&gt;

&lt;p&gt;Repository is a critical part of the entity lifecycle that allows us to persist domain entities. In the domain layer we create a contract for application or domain services. Using that contract each service can access domain models directly to find the needed information. You could create a generic repository interface, defining all kinds of common methods. At this moment you are possibly asking yourself: and specifically in what place in schema I can see Repository Interface? Nowhere. But let’s look at Domain Services and we are going to get to the truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain services
&lt;/h3&gt;

&lt;p&gt;These one encapsulates domain logic and concepts that are not naturally modeled as value objects or entities in your model. Domain services have &lt;em&gt;no identity or state&lt;/em&gt;; their responsibility is to orchestrate business logic using entities and value objects. If the domain service implementation requires some specific technology (for example database access, or SMTP server access or whatever), its implementation must live in the infrastructure layer. The domain simply doesn't care about implementations, if the business experts talk about something and we decide to make this "something" a contract, it must live in the Domain layer. Therefore Repository Interface is a Domain Service and Repository is an Infrastructure Service. &lt;/p&gt;

&lt;h3&gt;
  
  
  Entities
&lt;/h3&gt;

&lt;p&gt;An entity represents a concept in your domain that is defined by its identity rather than its attributes. Although an entity’s identity remains fixed throughout its lifecycle, its attributes may change. An &lt;em&gt;example&lt;/em&gt; of an entity is a User. It’s unique identity won’t change once it is set but its name, address, etc., can be altered many times. Entities are mutable as the attributes can change.&lt;/p&gt;

&lt;h3&gt;
  
  
  Value objects (VO)
&lt;/h3&gt;

&lt;p&gt;VO represent the elements of your domain that are known and defined only by their attributes. Value objects don’t need identity because they are always associated with another object and are therefore understood within a particular context. For instance, you may have an User entity that uses value objects to represent the user address, account information and so on. Not one of these characteristics needs identity itself because it only has meaning within the context of being attached to an order. An User Address that is not attached to User does not have meaning. Because they are defined by their attributes, value objects are treated as immutable. That means, once constructed, they can never alter their state. &lt;/p&gt;

&lt;p&gt;I’ve provided in the project the following data flow bus, that elaborate relationship between domain elements: create DTO from request data, create VO from the DTO and persist Entity, initializing from the VO. And backwards: fetch Entity, create VO and return DTO in Response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain events
&lt;/h3&gt;

&lt;p&gt;signify something that has happened in the problem domain that the business cares about. You can use events to record changes to a model in an audit fashion, or you can use them as a form of communication across aggregates. Often an operation on a single aggregate root can result in side effects that are outside the aggregate root boundary. Other aggregates within the model can listen for events and act accordingly. We are using Doctrine lifecycle events and it’s a perfect example of Domain Events.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;em&gt;Application layer&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flxxwet9f6tjzu1abqij9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flxxwet9f6tjzu1abqij9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This layer is responsible for the navigation between the UI and other layers in the bounded context as well as the interaction with application layers of other bounded contexts. There we can perform the basic (non business related) validation on the user input data before transmitting it to the other (lower) layers of the application. And it should not contain any business or domain related logic. But it definitely should perform tasks from the UI request via services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validator
&lt;/h3&gt;

&lt;p&gt;Typically, the data received by your application will be some flavor of DTO. Having successfully parsed the command into types the domain model understands, the command is executed in the domain, which may still reject the command on the grounds that it would violate the business invariant (the account doesn't exist yet, the account is blocked, etc.). In other words, the business validation is going to happen in the domain model, after the application layer validates the inputs. The implementation of the validation rules will normally live either in the constructor of the value type, or within the factory method used to construct the value type. Basically, you restrict the construction of the objects so that they are guaranteed to be valid, isolating the logic in one place, and invoking it at the process boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Provider
&lt;/h3&gt;

&lt;p&gt;It’s necessary to use providers to elaborate with our framework for orchestrating services in containers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command Handlers
&lt;/h3&gt;

&lt;p&gt;This structure is semantically similar to the application service layer, because here we store handlers that operate with commands (or task requests in our case) and call services according to task. Command itself is a business intention, something you want a system to do. Keep the definition of the commands in the domain. Technically it is just a pure DTO and DTO is what we have for our commands. The name of the command should always be imperative, like "CreateUser", "DeleteScenario". One command is handled only by one command handler. &lt;/p&gt;

&lt;h3&gt;
  
  
  EventHandlers
&lt;/h3&gt;

&lt;p&gt;There is a benefit to having event handlers that live in the application service layer in addition to those that live in the domain. These event handlers tend to carry out infrastructural tasks like sending e‐mails. Note that these handlers are not part of UL or the domain.&lt;br&gt;
One important responsibility of application service layer handlers is that they trigger communication with external bounded contexts. We have Notifiers (sms, email) as an &lt;em&gt;example&lt;/em&gt; of Event Handler.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Services
&lt;/h3&gt;

&lt;p&gt;We are using them as orchestrators that receive a request from the client, look up the object(s) that know how to handle the request, ask them to handle the request, store the result and send back a response to the client. The application services should not need to make any decisions themselves. &lt;/p&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;p&gt;Use Case in general is a business scenario and DDD defines it this way in theory and as a pure analog with Application Service in diagram or code structure. &lt;br&gt;
Although, in practice, with real code in real projects, we have to build a bridge between UI data and an application service. We additionally have to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firstly, integrate the middleware layer (application validation check, do authorization check, data access (permissions to perform the Use Case) check, etc.) and initialize Use Case with data. In general, we need to assemble UI data into Use Case. So, I call it UseCaseAssembler.&lt;/li&gt;
&lt;li&gt;Secondly, call service according to use case purpose, transform  data, returned by service into Use Case Response and pass it to the UI layer. It’s definitely Use Case itself.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;em&gt;Infrastructure Layer&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4no5152ydacwa3bipxp3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4no5152ydacwa3bipxp3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can be described by shared libraries for Domain, Application, and UI layers. As you can probably notice from schematic, this layer also communicates with external systems. What shall we have here?&lt;/p&gt;

&lt;h3&gt;
  
  
  Builder
&lt;/h3&gt;

&lt;p&gt;If the creation of an entity or a value object is sufficiently complex, you should delegate the construction to a factory. A factory ensures that all invariants are met before the domain object is created. You can also use factories when re‐creating domain objects from persistent storage. And in our case it would be a builder, because &lt;em&gt;DTO&amp;lt;-&amp;gt;VO&amp;lt;-&amp;gt;Entity&lt;/em&gt; transformation goes in here and we are building those domain elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repositories
&lt;/h3&gt;

&lt;p&gt;A domain model needs a methodology for persisting and hydrating an aggregate. Because an aggregate is treated as an atomic unit, you should not be able to persist changes to an aggregate without persisting the entire aggregate. A repository is a pattern that abstracts the underlying persistence store from the model allowing you to create a model without thinking about infrastructure concerns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service
&lt;/h3&gt;

&lt;p&gt;Services in the infrastructure layer are services which implement an interface from the domain layer. In the domain layer, you define an interface with actions we want to have.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hibernate[Doctrine] Directory
&lt;/h3&gt;

&lt;p&gt;This is an example of real-world needed infrastructure implementation. We keep here custom ORM types that we are using in our Entities. &lt;/p&gt;

&lt;h3&gt;
  
  
  Task Request
&lt;/h3&gt;

&lt;p&gt;It’s my own extended version of a standard CQRS command request. Our service has two types of API requests: external "usecase" type and command request type, that can be external and internal. The second type can be managed differently, depending on it’s goal. It can be a simple external request to handle a command. Another time it can be a complex task with transaction in it. So we should use a different approach for every version of the task according to the configuration pre-set. Either way we create a task request and manage it using a message broker. You can overlook it in my specific &lt;a href="https://dev.to/soulwife/bounded-context-command-task-requested-29k3"&gt;article&lt;/a&gt; if you are interested in this topic.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;em&gt;Presentation Layer (UI)&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz1fcq32gd92cv3tmipdk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fz1fcq32gd92cv3tmipdk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A UI Layer is responsible for presenting information to the user and interpreting user commands.So it should translate incoming requests to method calls for the application layer and in the case of web services, translate the return values to responses. It may also contain Controller classes as in classical MVC. &lt;br&gt;
We are using &lt;strong&gt;GraphQL&lt;/strong&gt;, so I am going to explain this Layer in example how we deal with requests and responses. We have one endpoint and specific types for input parameters and output data. So we can create a request from the input query and return a response after resolving this request. All of it takes place in a specific for each Use Case &lt;strong&gt;Resolver&lt;/strong&gt;.&lt;br&gt;
Our &lt;strong&gt;Schema&lt;/strong&gt; is a data contract. We're telling anyone who uses this API, "hey, this is going to be the format that you can always expect to see from this API call". And you are going to need a &lt;strong&gt;Presenter&lt;/strong&gt; to perform complex logic for composing data from entities in case you need it. More about it &lt;a href="https://dev.to/soulwife/graphql-change-for-the-best-4pf6"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Full blueprint
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8do9i39uy0a5rb7ff2tz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8do9i39uy0a5rb7ff2tz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, we almost did it. I mean, if someone had provided me the full example of an enterprise project three years ago, I would be more than happy. But no, it was not gonna happen then, but now I have one for you. &lt;/p&gt;

&lt;p&gt;I’ve described all context directories, except one. And this one hidden gem is the &lt;strong&gt;Shared Kernel&lt;/strong&gt;. It’s a way of cross-context communication in which two or more contexts share a common model. You can learn all other ways in &lt;a href="https://www.google.com/search?q=implementing+domain+driven+design+vaughn+vernon&amp;amp;rlz=1C1GCEA_enGB824GB824&amp;amp;oq=implementing+domain+driven+design+&amp;amp;aqs=chrome.2.0j69i57j0l4.8410j0j7&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;Vaughn Vernon’s IDDD book&lt;/a&gt; (such as Customer Supplier, Conformist, Partnership and other). In my project I prefer to use the &lt;strong&gt;Shared Kernel&lt;/strong&gt; concept linked with &lt;strong&gt;Anti Corruption Layer&lt;/strong&gt; on one hand and &lt;strong&gt;Partnership&lt;/strong&gt; relationship on the other. The first one combined approach will guarantee the integrity of models via read only access and usability. And Partnership is convenient to use via messaging patterns, that I described earlier.&lt;/p&gt;

&lt;p&gt;When integrating your bounded contexts, it’s important to get an idea from the business what its nonfunctional requirements are so that you can choose an integration strategy that lets you meet them with the least amount of effort. Some options, such as messaging, take more effort to implement, but they provide a solid foundation for achieving high scalability and reliability. On the other hand, if you don’t have such strong scalability requirements, you can integrate bounded contexts with a small initial effort using database integration. You can then get on with shipping other important features sooner and integrate CQRS later on. Unfortunately, you can’t just ask the business how scalable a system needs to be or how reliable it should be. In my practice, trying to give them both scenarios and explaining the costs of each scenario is the best approach.&lt;/p&gt;




&lt;p&gt;Thank you, all, who have read this "long read"! I hope, that you found it useful. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep your code clean and clear and yourself safe and sound!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ddd</category>
      <category>programming</category>
      <category>architecture</category>
      <category>domaindrivendesign</category>
    </item>
  </channel>
</rss>
