<?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>DEV Community: Bruno Souza</title>
    <description>The latest articles on DEV Community by Bruno Souza (@brunosouzas).</description>
    <link>https://dev.to/brunosouzas</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%2F554255%2F58ecb171-9788-44ab-aeec-b2e03df8e1c1.jpeg</url>
      <title>DEV Community: Bruno Souza</title>
      <link>https://dev.to/brunosouzas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brunosouzas"/>
    <language>en</language>
    <item>
      <title>Liskov Substitution Principle (LSP) in MuleSoft: Ensuring Consistency and Substitutability</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Mon, 14 Apr 2025 09:17:14 +0000</pubDate>
      <link>https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8</link>
      <guid>https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What is LSP?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Liskov Substitution Principle states that &lt;strong&gt;objects of a base class should be substitutable by objects of their subclasses without causing issues in the program&lt;/strong&gt;. In the context of MuleSoft, this means that any component expecting a specific behavior (such as an API response format) should function correctly even when handling variations of that component.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why Is LSP Important for MuleSoft?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In integration development, it is common to deal with heterogeneous systems (ERPs, CRMs, databases) that evolve independently. LSP ensures that changes in these systems do not break existing flows. For example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Consistency in API Responses:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If an API returns &lt;code&gt;totalPrice&lt;/code&gt; for domestic orders, international orders should not replace this field with &lt;code&gt;tax&lt;/code&gt; without ensuring compatibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Legacy System Replacement:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When migrating from an old ERP to a new one, flows should continue functioning without modifications, as long as the new system respects existing contracts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Extensibility Without Regression:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New types of orders (e.g., subscriptions) should be processed without breaking flows that depend on the original format.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Consequences of Violating LSP&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Broken Flows:&lt;/strong&gt; Consumers fail when receiving unexpected fields or altered formats.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constant Rework:&lt;/strong&gt; Each new integration requires manual adjustments across multiple flows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of Confidence:&lt;/strong&gt; Teams avoid making changes due to fear of collateral impacts.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Practical Example: Violating LSP (Before)&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Violation Scenario&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Suppose our order system returns inconsistent responses for different types of orders. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standard Order:&lt;/strong&gt; Returns &lt;code&gt;orderId&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, and &lt;code&gt;totalPrice&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Express Order:&lt;/strong&gt; Returns &lt;code&gt;orderId&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;totalPrice&lt;/code&gt;, and &lt;code&gt;additionalInfo&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;International Order:&lt;/strong&gt; Returns &lt;code&gt;orderId&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, and &lt;code&gt;tax&lt;/code&gt; (instead of &lt;code&gt;totalPrice&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This violates LSP because API consumers cannot rely on a consistent format, even for "subtypes" of orders.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Code That Violates LSP&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Incomplete RAML Contract (Before):&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#%RAML 1.0&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Order API&lt;/span&gt;
&lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;OrderResponse&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;totalPrice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Inconsistent DataWeave Transformation (Before):&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;transform&lt;/span&gt; &lt;span class="na"&gt;doc:name=&lt;/span&gt;&lt;span class="s"&gt;"Generate Response"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dw:set-payload&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;![CDATA[%dw 2.0
        output application/json
        ---
        {
            orderId: payload.orderId,
            status: "processed",
            totalPrice: payload.totalPrice,
            additionalInfo: "Express delivery" // Field not defined in the contract!
        }
    ]]&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/dw:set-payload&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/transform&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problems:&lt;/strong&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The field &lt;code&gt;additionalInfo&lt;/code&gt; is not defined in the RAML contract, violating consumer expectations.
&lt;/li&gt;
&lt;li&gt;International orders return &lt;code&gt;tax&lt;/code&gt; instead of &lt;code&gt;totalPrice&lt;/code&gt;, breaking the expected structure.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Applying LSP (After)&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Update RAML Contract to Support Variations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Define optional fields or extensions to accommodate variations without breaking the base structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#%RAML 1.0&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Order API&lt;/span&gt;
&lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;OrderResponse&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;totalPrice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;number&lt;/span&gt;
      &lt;span class="s"&gt;additionalInfo?&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string  // Optional field&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Ensure Consistency in Transformations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Modify the DataWeave transformation to follow the contract, even for order subtypes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;transform&lt;/span&gt; &lt;span class="na"&gt;doc:name=&lt;/span&gt;&lt;span class="s"&gt;"Generate Response"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dw:set-payload&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;![CDATA[%dw 2.0
        output application/json
        ---
        {
            orderId: payload.orderId,
            status: "processed",
            totalPrice: payload.totalPrice default payload.tax, // Ensures consistency
            additionalInfo: payload.additionalInfo default null
        }
    ]]&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/dw:set-payload&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/transform&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Examples of Valid Outputs (After)&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Standard Order:&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"processed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"totalPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"additionalInfo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Express Order:&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"processed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"totalPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;115&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"additionalInfo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Express delivery"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;International Order:&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orderId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"789"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"processed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"totalPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Tax&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;converted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;totalPrice&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"additionalInfo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;How Does This Resolve the LSP Violation?&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Structural Consistency:&lt;/strong&gt; All order types return the same mandatory fields (&lt;code&gt;orderId&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;totalPrice&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlled Extensibility:&lt;/strong&gt; Optional fields (&lt;code&gt;additionalInfo&lt;/code&gt;) are documented in the contract and do not break existing consumers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe Substitution:&lt;/strong&gt; Any order subtype can be used in place of another without altering expected behavior.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Checklist for Correctly Applying LSP&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Do all subtypes follow the base API contract?
&lt;/li&gt;
&lt;li&gt;[ ] Are additional fields optional and documented?
&lt;/li&gt;
&lt;li&gt;[ ] Do transformations ensure consistent data conversion (e.g., &lt;code&gt;tax&lt;/code&gt; → &lt;code&gt;totalPrice&lt;/code&gt;)?
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Next Steps&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we’ve covered LSP, let’s explore the next principle: &lt;strong&gt;Interface Segregation Principle (ISP)&lt;/strong&gt; — designing APIs with focused endpoints to prevent consumers from depending on unnecessary functionalities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e"&gt;← Previous Principle: OCP&lt;/a&gt; | &lt;a href="https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd"&gt;→ Next Principle: ISP&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  SOLID in MuleSoft – The Art of Designing Evolutionary Integrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complete Series:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg"&gt;Introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8"&gt;Single Responsibility Principle (SRP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e"&gt;Open/Closed Principle (OCP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8"&gt;Liskov Substitution Principle (LSP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd"&gt;Interface Segregation Principle (ISP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn"&gt;Dependency Inversion Principle (DIP)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Interface Segregation Principle (ISP) in MuleSoft: Specific Interfaces for Specific Needs</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Mon, 14 Apr 2025 09:17:05 +0000</pubDate>
      <link>https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd</link>
      <guid>https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What is ISP?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Interface Segregation Principle (ISP) states that &lt;strong&gt;no client should be forced to depend on methods or interfaces it does not use&lt;/strong&gt;. In other words, it is better to have several small and specific interfaces than one large and generic interface.&lt;/p&gt;

&lt;p&gt;In the context of MuleSoft, ISP can be applied by designing APIs and flows that segregate responsibilities into different layers or endpoints, ensuring that each consumer uses only what they truly need.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why Is ISP Important for MuleSoft?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine our order system has a monolithic API with multiple endpoints related to orders, inventory, and payments. If an API consumer only needs data for a specific order, they would still be forced to deal with endpoints or parameters related to inventory or payments—violating ISP.&lt;/p&gt;

&lt;p&gt;This approach can lead to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unnecessary complexity:&lt;/strong&gt; Consumers need to understand parts of the API that are irrelevant to them.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low reusability:&lt;/strong&gt; Generic APIs become difficult to adapt for new consumers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High maintenance costs:&lt;/strong&gt; Changes in one part of the API affect all consumers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By applying ISP, we can design APIs and flows that are more specific and tailored to consumers' needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How to Apply ISP in the Order System?&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Divide APIs into Layers Using API-Led Connectivity&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;MuleSoft promotes the use of the &lt;strong&gt;API-Led Connectivity&lt;/strong&gt; pattern, which divides APIs into three main layers:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;System APIs:&lt;/strong&gt; Interfaces that expose raw data directly from underlying systems (e.g., ERP, CRM).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process APIs:&lt;/strong&gt; Interfaces that aggregate and transform data between systems.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experience APIs:&lt;/strong&gt; Interfaces formatted for end consumers (e.g., mobile or web applications).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach ensures that each consumer uses only the relevant interfaces for their needs.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – API Layers:&lt;/strong&gt;
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Example Endpoint&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;System API&lt;/td&gt;
&lt;td&gt;Expose raw ERP data&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/erp/orders&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Process API&lt;/td&gt;
&lt;td&gt;Aggregate order and inventory data&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/process/orders-with-stock&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Experience API&lt;/td&gt;
&lt;td&gt;Formatted data for applications&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/mobile/orders&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. Create APIs Specific to Consumers&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Instead of creating a single generic API for all consumers, divide endpoints based on specific needs.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – Before (violating ISP):&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#%RAML 1.0&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Order API&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;

&lt;span class="na"&gt;/resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;/orders&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Returns orders with inventory and payment information.&lt;/span&gt;
      &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;200&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;application/json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
              &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
                &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;array&lt;/span&gt;
                &lt;span class="na"&gt;stockAvailability&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;boolean&lt;/span&gt;
                &lt;span class="na"&gt;paymentStatus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, all API consumers are forced to deal with inventory and payment information even if they only need basic order details.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – After (applying ISP):&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#%RAML 1.0&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Order API&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;

&lt;span class="na"&gt;/resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;/orders&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Returns only basic order details.&lt;/span&gt;
      &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;200&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;application/json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
              &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
                &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;array&lt;/span&gt;

  &lt;span class="na"&gt;/orders/stock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Returns stock availability for order items.&lt;/span&gt;
      &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;200&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;application/json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
              &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
                &lt;span class="na"&gt;stockAvailability&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;boolean&lt;/span&gt;

  &lt;span class="na"&gt;/orders/payment-status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Returns payment status for an order.&lt;/span&gt;
      &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;200&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;application/json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
              &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;orderId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
                &lt;span class="na"&gt;paymentStatus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, each consumer can access only the relevant endpoints for their needs.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. Modularize Flows with Dedicated Subflows&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Similar to SRP, modularizing flows into dedicated subflows also helps apply ISP. Each subflow can be designed to handle a specific responsibility.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – Modularized Flow by Responsibility&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processOrder"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;http:listener&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"/orders"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Data Validation --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;flow-ref&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"validateOrder"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Data Transformation --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;flow-ref&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"transformOrder"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/flow&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"validateOrder"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Specific validations --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"transformOrder"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Specific transformations --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of ISP in the Order System&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity:&lt;/strong&gt; Consumers access only the information relevant to their needs.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusability:&lt;/strong&gt; Specific APIs are easier to adapt for new use cases.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Maintenance:&lt;/strong&gt; Changes in one part of the API do not affect all consumers.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Checklist for Applying ISP in MuleSoft&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Have APIs been divided into layers (System, Process, Experience)?
&lt;/li&gt;
&lt;li&gt;[ ] Are endpoints specific to different types of consumers?
&lt;/li&gt;
&lt;li&gt;[ ] Have flows been modularized by responsibility?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Next Steps&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we’ve covered ISP, let’s move on to the final principle in the SOLID series: the &lt;strong&gt;Dependency Inversion Principle (DIP)&lt;/strong&gt; — designing flows that depend on abstractions rather than implementations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8"&gt;← Previous Principle: LSP&lt;/a&gt; | &lt;a href="https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn"&gt;→ Next Principle: DIP&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  SOLID in MuleSoft – The Art of Designing Evolutionary Integrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complete Series:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg"&gt;Introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8"&gt;Single Responsibility Principle (SRP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e"&gt;Open/Closed Principle (OCP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8"&gt;Liskov Substitution Principle (LSP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd"&gt;Interface Segregation Principle (ISP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn"&gt;Dependency Inversion Principle (DIP)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Dependency Inversion Principle (DIP) in MuleSoft: Rely on Abstractions, Not Implementations</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Mon, 14 Apr 2025 09:16:56 +0000</pubDate>
      <link>https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn</link>
      <guid>https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What is DIP?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Dependency Inversion Principle states that &lt;strong&gt;high-level modules should not depend directly on low-level modules; both should depend on abstractions&lt;/strong&gt;. Additionally, &lt;strong&gt;abstractions should not depend on details; details should depend on abstractions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the context of MuleSoft, this means designing flows and APIs that rely on interfaces or abstractions (such as System APIs or generic connectors) rather than specific implementations (like a database or legacy system). This approach reduces coupling between components and facilitates easier replacement or extension of functionalities.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why Is DIP Important for MuleSoft?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine your order system directly depends on a specific database (e.g., MySQL) to retrieve order details. If you need to migrate to another system (e.g., MongoDB or an external API), all flows connected to MySQL would need to be modified—violating DIP.&lt;/p&gt;

&lt;p&gt;This approach can lead to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High coupling:&lt;/strong&gt; Flows become rigidly tied to a specific implementation.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low flexibility:&lt;/strong&gt; Changes in the underlying system require modifications across all dependent flows.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expensive maintenance:&lt;/strong&gt; Replacing or upgrading technologies becomes complex and risky.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By applying DIP, we can design flows that rely on abstractions (like System APIs), allowing greater flexibility and easier maintenance.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How to Apply DIP in the Order System?&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Use System APIs to Abstract Underlying Systems&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Instead of directly accessing a database or internal system, create a &lt;strong&gt;System API&lt;/strong&gt; that abstracts implementation details. The System API acts as an intermediary between the main flows and the underlying systems.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – Before (violating DIP):&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;db:select&lt;/span&gt; &lt;span class="na"&gt;doc:name=&lt;/span&gt;&lt;span class="s"&gt;"Fetch Order"&lt;/span&gt; &lt;span class="na"&gt;config-ref=&lt;/span&gt;&lt;span class="s"&gt;"MySQL_Configuration"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;db:sql&amp;gt;&lt;/span&gt;SELECT * FROM orders WHERE order_id = #[attributes.queryParams.orderId]&lt;span class="nt"&gt;&amp;lt;/db:sql&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/db:select&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the flow is directly coupled to MySQL. Migrating to another system (e.g., MongoDB) would require modifying this flow.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – After (applying DIP):&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"getOrderDetails"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;http:request&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt; &lt;span class="na"&gt;url=&lt;/span&gt;&lt;span class="s"&gt;"http://system-api/orders?orderId=#[attributes.queryParams.orderId]"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/flow&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The flow depends on the System API (&lt;code&gt;system-api&lt;/code&gt;), which abstracts the underlying implementation.&lt;/li&gt;
&lt;li&gt;The System API can be updated to use another database or system without impacting consumers.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. Centralize Configurations Using Shared Libraries or External Files&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Another way to apply DIP is by centralizing sensitive configurations (such as database connections) in shared libraries or external files. This prevents flows from being directly tied to specific configurations.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – Before (violating DIP):&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;db:select&lt;/span&gt; &lt;span class="na"&gt;doc:name=&lt;/span&gt;&lt;span class="s"&gt;"Fetch Order"&lt;/span&gt; &lt;span class="na"&gt;config-ref=&lt;/span&gt;&lt;span class="s"&gt;"MySQL_Configuration"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;db:sql&amp;gt;&lt;/span&gt;SELECT * FROM orders WHERE order_id = #[attributes.queryParams.orderId]&lt;span class="nt"&gt;&amp;lt;/db:sql&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/db:select&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the connector is hardcoded into the flow. Changing credentials or migrating to another database would require modifying the flow.&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – After (applying DIP):&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"getOrderFromDB"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;db:select&lt;/span&gt; &lt;span class="na"&gt;doc:name=&lt;/span&gt;&lt;span class="s"&gt;"Fetch Order"&lt;/span&gt; &lt;span class="na"&gt;config-ref=&lt;/span&gt;&lt;span class="s"&gt;"${db.config}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;db:sql&amp;gt;&lt;/span&gt;SELECT * FROM orders WHERE order_id = #[attributes.queryParams.orderId]&lt;span class="nt"&gt;&amp;lt;/db:sql&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/db:select&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The database configuration (&lt;code&gt;db.config&lt;/code&gt;) is managed externally (e.g., in a &lt;code&gt;.properties&lt;/code&gt; file or shared library).&lt;/li&gt;
&lt;li&gt;Changes can be made without modifying the flows.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. Use Generic Connectors to Reduce Coupling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;MuleSoft offers generic connectors, such as HTTP and Database, which can be dynamically configured for different systems. This reduces direct dependency on specific implementations.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Example – Dynamic HTTP Connector:&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"getOrderDetails"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Dynamically configured endpoint --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;http:request&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt; &lt;span class="na"&gt;url=&lt;/span&gt;&lt;span class="s"&gt;"#[vars.apiEndpoint]/orders"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/flow&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The variable &lt;code&gt;vars.apiEndpoint&lt;/code&gt; can be dynamically configured based on the environment (e.g., development, production).&lt;/li&gt;
&lt;li&gt;The flow is not tied to a fixed endpoint.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Summary of Applying DIP in the Order System&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Before:&lt;/strong&gt; Flow directly connected to MySQL using the Database connector.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After:&lt;/strong&gt; Flow connected to a System API (&lt;code&gt;order-system-api&lt;/code&gt;) that abstracts the database implementation.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduces coupling between flows and underlying systems.&lt;/li&gt;
&lt;li&gt;Simplifies updates or replacements of backend systems without impacting consumers.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of DIP in the Order System&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; Changes in underlying systems do not impact main flows.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusability:&lt;/strong&gt; Intermediate APIs can be reused across projects and consumers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Maintenance:&lt;/strong&gt; Centralized dependencies make updates easier.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Checklist for Applying DIP in MuleSoft&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Do flows depend on intermediate APIs rather than direct implementations?
&lt;/li&gt;
&lt;li&gt;[ ] Are sensitive configurations centralized in external files or shared libraries?
&lt;/li&gt;
&lt;li&gt;[ ] Are generic connectors used to reduce coupling?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Impact of SOLID Principles on MuleSoft&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Throughout this series, we explored how SOLID principles can transform a MuleSoft system into a more robust, scalable, and maintainable solution. Using the practical example of an order system, we saw how each principle addresses common challenges in integrations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SRP (Single Responsibility Principle):&lt;/strong&gt; Simplified flows by separating responsibilities into dedicated subflows.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OCP (Open/Closed Principle):&lt;/strong&gt; Enabled extensibility by adding new functionalities without modifying existing flows.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LSP (Liskov Substitution Principle):&lt;/strong&gt; Ensured consistency in data formats across different types of orders.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ISP (Interface Segregation Principle):&lt;/strong&gt; Divided APIs into specific layers tailored to consumer needs.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DIP (Dependency Inversion Principle):&lt;/strong&gt; Decoupled flows from implementations using abstractions like System APIs.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Achieved Benefits&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced complexity:&lt;/strong&gt; Smaller, focused flows are easier to understand and debug.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified maintenance:&lt;/strong&gt; Changes in one component do not impact other modules.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; New functionalities can be added without breaking existing systems.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved developer experience:&lt;/strong&gt; Modular design accelerates onboarding and team collaboration.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Next Steps&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To apply these concepts in your own MuleSoft projects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Audit existing flows to identify violations of SOLID principles.&lt;/li&gt;
&lt;li&gt;Modularize components using patterns like API-Led Connectivity.&lt;/li&gt;
&lt;li&gt;Centralize sensitive configurations using shared libraries or Object Store.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  SOLID in MuleSoft – The Art of Designing Evolutionary Integrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complete Series:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg"&gt;Introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8"&gt;Single Responsibility Principle (SRP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e"&gt;Open/Closed Principle (OCP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8"&gt;Liskov Substitution Principle (LSP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd"&gt;Interface Segregation Principle (ISP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn"&gt;Dependency Inversion Principle (DIP)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Open/Closed Principle (OCP) in MuleSoft: APIs and Flows That Evolve Without Breaking</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Mon, 14 Apr 2025 09:16:45 +0000</pubDate>
      <link>https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e</link>
      <guid>https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What is OCP?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Open/Closed Principle states that &lt;strong&gt;a component should be open for extension but closed for modification&lt;/strong&gt;. This means you should be able to add new functionality to the system without altering existing code, minimizing the risk of introducing errors in already tested components.&lt;/p&gt;

&lt;p&gt;In the context of MuleSoft, this involves designing flows that allow the addition of new behaviors or integrations without modifying the main flows.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why Is OCP Important in Integrations?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine that your order system needs to add support for the &lt;strong&gt;PayPal&lt;/strong&gt; payment method, alongside existing methods like credit card and bank slip. If the payment logic is embedded directly in the main flow, any change would require modifying existing code—violating OCP.&lt;/p&gt;

&lt;p&gt;This approach can lead to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regression risks:&lt;/strong&gt; Changes may break existing functionalities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High maintenance costs:&lt;/strong&gt; Each new feature requires alterations to already implemented flows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low scalability:&lt;/strong&gt; The main flow becomes increasingly complex and harder to manage.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How to Apply OCP in the Payment System?&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Practical Example – Before (Violating OCP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this example, the main flow contains routing logic for existing methods (&lt;strong&gt;creditCard&lt;/strong&gt; and &lt;strong&gt;bankSlip&lt;/strong&gt;). Adding a new method (like PayPal) would require modifying the main flow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processPayment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;choice&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;when&lt;/span&gt; &lt;span class="na"&gt;expression=&lt;/span&gt;&lt;span class="s"&gt;"#[payload.paymentMethod == 'creditCard']"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;flow-ref&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processCreditCard"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/when&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;when&lt;/span&gt; &lt;span class="na"&gt;expression=&lt;/span&gt;&lt;span class="s"&gt;"#[payload.paymentMethod == 'bankSlip']"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;flow-ref&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processBankSlip"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/when&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;otherwise&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;set-payload&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Unsupported payment method"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/otherwise&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/choice&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/flow&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Existing subflows --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processCreditCard"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Logic for credit card --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;logger&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"Processing payment via credit card"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processBankSlip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Logic for bank slip --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;logger&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"Processing payment via bank slip"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To add PayPal, you would need to modify the main flow by adding a new condition, violating OCP.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. Practical Example – After (Applying OCP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here, we use a YAML file to configure payment methods dynamically. New methods can be added without altering the main flow.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 1: Configuration in YAML (payment-config.yaml)&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;payment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;flow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;creditCard&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;processCreditCard&lt;/span&gt;
    &lt;span class="na"&gt;bankSlip&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;processBankSlip&lt;/span&gt;
    &lt;span class="na"&gt;payPal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;processPayPal&lt;/span&gt; &lt;span class="c1"&gt;# New method added&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Step 2: Main Flow with Dynamic Routing&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processPayment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Retrieve subflow name from YAML --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;set-variable&lt;/span&gt; 
        &lt;span class="na"&gt;variableName=&lt;/span&gt;&lt;span class="s"&gt;"paymentFlow"&lt;/span&gt; 
        &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"#[p('payment.flow.' ++ payload.paymentMethod)]"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Dynamic routing --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;choice&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;when&lt;/span&gt; &lt;span class="na"&gt;expression=&lt;/span&gt;&lt;span class="s"&gt;"#[vars.paymentFlow != null]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;flow-ref&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"#[vars.paymentFlow]"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/when&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;otherwise&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;raise-error&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"ORDER:PAYMENT_METHOD_NOT_SUPPORTED"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/otherwise&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/choice&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/flow&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Existing subflows (unchanged) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processCreditCard"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;logger&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"Processing payment via credit card"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processBankSlip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;logger&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"Processing payment via bank slip"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- New subflow for PayPal --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processPayPal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;logger&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"Processing payment via PayPal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;How Does This Respect OCP?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Extensibility Without Modification:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To add &lt;strong&gt;PayPal&lt;/strong&gt;, simply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;payPal: processPayPal&lt;/code&gt; in YAML.&lt;/li&gt;
&lt;li&gt;Create the &lt;code&gt;processPayPal&lt;/code&gt; subflow.&lt;/li&gt;
&lt;li&gt;No changes to the main flow are required.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Decoupling:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The main flow depends only on the subflow name configured externally, not on specific implementations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Benefits of This Approach&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Risks:&lt;/strong&gt; New methods can be added without touching the main flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized Configuration:&lt;/strong&gt; Payment methods are managed via YAML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Cohesion:&lt;/strong&gt; Each subflow has a single responsibility (SRP).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Checklist for Applying OCP in MuleSoft&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] The main flow is not modified when new functionalities are added.
&lt;/li&gt;
&lt;li&gt;[ ] New behaviors are configured externally (YAML/properties).
&lt;/li&gt;
&lt;li&gt;[ ] Specialized subflows are independent of the main flow.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Next Steps&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we’ve covered OCP, let’s move on to the next principle: &lt;strong&gt;Liskov Substitution Principle (LSP)&lt;/strong&gt; — ensuring consistency in API responses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8"&gt;← Previous Principle: SRP&lt;/a&gt; | &lt;a href="https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8"&gt;→ Next Principle: LSP&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  SOLID in MuleSoft – The Art of Designing Evolutionary Integrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complete Series:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg"&gt;Introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8"&gt;Single Responsibility Principle (SRP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e"&gt;Open/Closed Principle (OCP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8"&gt;Liskov Substitution Principle (LSP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd"&gt;Interface Segregation Principle (ISP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn"&gt;Dependency Inversion Principle (DIP)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Single Responsibility Principle (SRP) in MuleSoft: Structuring Flows with Focused Responsibilities</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Mon, 14 Apr 2025 09:16:35 +0000</pubDate>
      <link>https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8</link>
      <guid>https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What is SRP?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt; states that &lt;strong&gt;a component should have only one reason to change&lt;/strong&gt;. In practical terms, this means that each part of a system should be dedicated to a single task or specific function.&lt;/p&gt;

&lt;p&gt;When applied to MuleSoft, SRP helps us design specialized flows and subflows, each focused on a well-defined responsibility. This results in systems that are more organized, easier to maintain, and scalable.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why is SRP Crucial in Integrations?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine an order system with a monolithic flow performing the following tasks:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validating order data (e.g., checking if &lt;code&gt;orderId&lt;/code&gt; exists).
&lt;/li&gt;
&lt;li&gt;Calculating the total order value based on items and quantities.
&lt;/li&gt;
&lt;li&gt;Sending data to an external ERP system.
&lt;/li&gt;
&lt;li&gt;Notifying the customer via SMS or email after processing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This flow violates SRP because it mixes multiple responsibilities in one place, making it difficult to understand, test, and modify. Any change in one of these responsibilities can impact the entire flow.&lt;/p&gt;

&lt;p&gt;By applying SRP, we can divide these responsibilities into dedicated subflows, making the system more modular and manageable.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;How to Apply SRP in the Order System?&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Divide Flows into Specialized Subflows&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In MuleSoft, responsibilities can be divided into dedicated subflows:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One subflow exclusively for validating order data.
&lt;/li&gt;
&lt;li&gt;Another for calculating the total order value.
&lt;/li&gt;
&lt;li&gt;A third for sending data to the ERP system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Practical Example – Before (violating SRP):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processOrder"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;http:listener&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"/orders"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Validation --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;choice&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;when&lt;/span&gt; &lt;span class="na"&gt;expression=&lt;/span&gt;&lt;span class="s"&gt;"#[payload.orderId == null]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;set-payload&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Order ID is missing"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/when&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/choice&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Calculation --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;transform&lt;/span&gt; &lt;span class="na"&gt;doc:name=&lt;/span&gt;&lt;span class="s"&gt;"Calculate Total"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dw:set-payload&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;![CDATA[%dw 2.0
            output application/json
            ---
            {
                orderId: payload.orderId,
                totalPrice: payload.price * payload.quantity
            }
        ]]&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/dw:set-payload&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/transform&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Sending to ERP --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;http:request&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt; &lt;span class="na"&gt;url=&lt;/span&gt;&lt;span class="s"&gt;"https://erp.example.com/api/orders"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/flow&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Practical Example – After (applying SRP):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"processOrder"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;http:listener&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"/orders"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;flow-ref&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"validateOrder"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;  &lt;span class="c"&gt;&amp;lt;!-- Dedicated subflow for validation --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;flow-ref&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"calculateTotal"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Dedicated subflow for calculation --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;flow-ref&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"sendToERP"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;      &lt;span class="c"&gt;&amp;lt;!-- Dedicated subflow for sending to ERP --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/flow&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"validateOrder"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;choice&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;when&lt;/span&gt; &lt;span class="na"&gt;expression=&lt;/span&gt;&lt;span class="s"&gt;"#[payload.orderId == null]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;set-payload&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Order ID is missing"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/when&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/choice&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"calculateTotal"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;transform&lt;/span&gt; &lt;span class="na"&gt;doc:name=&lt;/span&gt;&lt;span class="s"&gt;"Calculate Total"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;dw:set-payload&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;![CDATA[%dw 2.0
            output application/json
            ---
            {
                orderId: payload.orderId,
                totalPrice: payload.price * payload.quantity
            }
        ]]&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/dw:set-payload&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/transform&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;sub-flow&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"sendToERP"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;http:request&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt; &lt;span class="na"&gt;url=&lt;/span&gt;&lt;span class="s"&gt;"https://erp.example.com/api/orders"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/sub-flow&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;2. Organize Files in a Structured Way&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In addition to logically dividing responsibilities, it is important to organize files physically to facilitate maintenance and scalability.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Recommended File Structure&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Main File:&lt;/strong&gt; &lt;code&gt;order-processing-api.xml&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Contains the main flow orchestrating the subflows.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subflows File:&lt;/strong&gt; &lt;code&gt;order-subflows.xml&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Groups all subflows related to orders.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utility File:&lt;/strong&gt; &lt;code&gt;common-utils.xml&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Contains reusable generic subflows such as error handling or logging.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Example Structure&lt;/strong&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
|-- main/
|   |-- mule/
|       |-- order-processing-api.xml
|       |-- order-subflows.xml
|       |-- common-utils.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;3. Reuse Subflows with Shared Libraries&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Specialized subflows can be reused across different APIs or projects using &lt;strong&gt;Shared Libraries&lt;/strong&gt; in MuleSoft.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Benefits of Shared Libraries&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Avoid code duplication by allowing reuse of generic subflows (e.g., validation or error handling).
&lt;/li&gt;
&lt;li&gt;Facilitate centralized updates without impacting multiple projects.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;How to Create Shared Libraries&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Publish generic subflows in the &lt;strong&gt;Anypoint Exchange&lt;/strong&gt; as reusable modules.&lt;/li&gt;
&lt;li&gt;Import these modules into other projects as needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details, see &lt;a href="https://docs.mulesoft.com/mule-runtime/4.4/shared-resources" rel="noopener noreferrer"&gt;MuleSoft's official documentation on Shared Libraries&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of SRP in the Order System&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Readability:&lt;/strong&gt; Smaller flows are easier to understand and document.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusability:&lt;/strong&gt; Specialized subflows can be used across multiple APIs or future projects (e.g., validation can be reused in stock-related APIs).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Maintenance:&lt;/strong&gt; Changes in one subflow do not impact other components.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Checklist for Applying SRP in MuleSoft&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Does each flow/subflow perform only one specific task?
&lt;/li&gt;
&lt;li&gt;[ ] Are reusable subflows created for common tasks?
&lt;/li&gt;
&lt;li&gt;[ ] Is the project structure conducive to maintenance and scalability?
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Next Steps&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we’ve covered SRP, let’s move on to the next principle in the series: the &lt;strong&gt;Open/Closed Principle (OCP)&lt;/strong&gt; — designing APIs and flows that evolve without breaking existing functionalities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg"&gt;← Introduction&lt;/a&gt; | &lt;a href="https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e"&gt;→ Next Principle: OCP&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  SOLID in MuleSoft – The Art of Designing Evolutionary Integrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complete Series:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg"&gt;Introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8"&gt;Single Responsibility Principle (SRP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e"&gt;Open/Closed Principle (OCP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8"&gt;Liskov Substitution Principle (LSP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd"&gt;Interface Segregation Principle (ISP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn"&gt;Dependency Inversion Principle (DIP)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>SOLID in MuleSoft – The Art of Designing Evolutionary Integrations</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Mon, 14 Apr 2025 09:16:24 +0000</pubDate>
      <link>https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg</link>
      <guid>https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine you are designing an API to process orders in an e-commerce system. This API needs to validate data, calculate values, send information to an ERP system, and notify customers—all while remaining scalable, easy to maintain, and ready for future changes. Without a structured approach, monolithic flows can quickly become difficult to understand, modify, and scale.&lt;/p&gt;

&lt;p&gt;This is where the &lt;strong&gt;SOLID&lt;/strong&gt; principles come into play. Created to guide the design of object-oriented systems, these principles help build robust, modular, and maintainable integrations. In this article, we will explore how to apply SOLID principles in the context of MuleSoft, using a fictional order system as a practical example.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Origin of SOLID Principles&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt; principles were introduced by &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Robert_C._Martin" rel="noopener noreferrer"&gt;Robert C. Martin&lt;/a&gt;&lt;/strong&gt; (also known as &lt;em&gt;Uncle Bob&lt;/em&gt;) in his famous 2000 essay, &lt;em&gt;"Design Principles and Design Patterns."&lt;/em&gt; Martin developed these concepts to address common software development issues such as rigid, fragile, and hard-to-evolve systems.&lt;/p&gt;

&lt;p&gt;The acronym &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt;&lt;/strong&gt; was later coined by &lt;strong&gt;Michael Feathers&lt;/strong&gt;, who organized the five principles into an easy-to-remember mnemonic. Additionally, some of the concepts were inspired by other pioneers in computer science:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Barbara_Liskov" rel="noopener noreferrer"&gt;Barbara Liskov&lt;/a&gt;&lt;/strong&gt; introduced the Liskov Substitution Principle (LSP), which is essential for ensuring consistency in object-oriented systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Bertrand_Meyer" rel="noopener noreferrer"&gt;Bertrand Meyer&lt;/a&gt;&lt;/strong&gt; conceived the Open/Closed Principle (OCP) in his book &lt;em&gt;"Object-Oriented Software Construction."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These principles quickly became cornerstones of modern software design, promoting modularity, flexibility, and maintainability.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Does SOLID Mean?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The acronym &lt;strong&gt;SOLID&lt;/strong&gt; represents five fundamental principles of object-oriented design. Let’s break each one down:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;S – Single Responsibility Principle (SRP)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Each class or component should have a single responsibility. In other words, there should only be one reason for a component to change.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; In a MuleSoft system, a subflow dedicated exclusively to validating order data adheres to this principle.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;O – Open/Closed Principle (OCP)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Components should be open for extension but closed for modification. This means you can add new functionality without altering existing code.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; A flow that uses dynamic routing to support new payment methods without modifying the main flow.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;L – Liskov Substitution Principle (LSP)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Subclasses should be substitutable for their base classes without altering the expected behavior of the system.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; MuleSoft APIs should return consistent responses regardless of the specific type of order being processed (standard, express, or international).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;I – Interface Segregation Principle (ISP)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
No client should be forced to depend on methods or interfaces it does not use. It is better to have multiple specific interfaces than one generic and bloated interface.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; Dividing APIs into layers (System APIs, Process APIs, and Experience APIs) to meet specific consumer needs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;D – Dependency Inversion Principle (DIP)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
High-level modules should not depend directly on low-level modules; both should depend on abstractions. Additionally, abstractions should not depend on details; details should depend on abstractions.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; A MuleSoft flow that depends on an abstract System API instead of directly accessing a database or legacy system.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These principles form the foundation for creating more flexible, scalable, and maintainable systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why Is SOLID Important?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In today’s world, where most companies connect multiple systems (such as ERPs, CRMs, and external platforms), maintaining these integrations is critical. When applied to MuleSoft, the SOLID principles offer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resilience:&lt;/strong&gt; APIs that support changes without breaking (e.g., updating a Salesforce connector without impacting the ERP).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency:&lt;/strong&gt; Significant reduction in debugging and maintenance time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future-readiness:&lt;/strong&gt; Adaptation to new technologies (such as IoT or Web3) without needing to rewrite flows from scratch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although MuleSoft already incorporates concepts aligned with SOLID principles (such as modularity through subflows or versioning in API Manager), few developers intentionally explore these practices. This article will demonstrate how to unlock MuleSoft’s full potential by adopting a principle-driven approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What Will You Learn?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this article, you will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to apply each SOLID principle in MuleSoft integrations with practical examples.&lt;/li&gt;
&lt;li&gt;Tips on structuring your projects for easier maintenance and scalability.&lt;/li&gt;
&lt;li&gt;A checklist to audit your flows and identify violations of SOLID principles.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Next Steps&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that we understand the origins and fundamentals of SOLID principles, let’s start with the first principle: the &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;—the foundation for creating focused and modular flows. Ready to dive in?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8"&gt;→ Next: SRP in MuleSoft&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  SOLID in MuleSoft – The Art of Designing Evolutionary Integrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complete Series:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/solid-in-mulesoft-the-art-of-designing-evolutionary-integrations-1hdg"&gt;Introduction&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/single-responsibility-principle-srp-in-mulesoft-structuring-flows-with-focused-responsibilities-4nh8"&gt;Single Responsibility Principle (SRP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/openclosed-principle-ocp-in-mulesoft-apis-and-flows-that-evolve-without-breaking-342e"&gt;Open/Closed Principle (OCP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/liskov-substitution-principle-lsp-in-mulesoft-ensuring-consistency-and-substitutability-28n8"&gt;Liskov Substitution Principle (LSP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/brunosouzas/interface-segregation-principle-isp-in-mulesoft-specific-interfaces-for-specific-needs-57jd"&gt;Interface Segregation Principle (ISP)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/brunosouzas/dependency-inversion-principle-dip-in-mulesoft-rely-on-abstractions-not-implementations-20nn"&gt;Dependency Inversion Principle (DIP)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Git Branch Strategy: Simplifying Collaboration and Development</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Mon, 12 Jun 2023 08:21:41 +0000</pubDate>
      <link>https://dev.to/brunosouzas/git-branch-strategy-simplifying-collaboration-and-development-2iko</link>
      <guid>https://dev.to/brunosouzas/git-branch-strategy-simplifying-collaboration-and-development-2iko</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;br&gt;
In software development, efficient collaboration and streamlined development processes are crucial to success. Git, a widely used version control system, offers powerful branching capabilities that allow teams to work on multiple features and bug fixes simultaneously. In this blog, we'll explore the importance of a well-defined git branch strategy and delve into two popular approaches: the Feature Branch Workflow and the Release Flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bc8NczT3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3l6gofoeul5ptcl7fay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bc8NczT3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3l6gofoeul5ptcl7fay.png" alt="Branch Structure" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The feature branch workflow:&lt;/strong&gt;&lt;br&gt;
Feature Branch Workflow is a simple yet effective strategy for managing branches in a Git repository. See how it works:&lt;br&gt;
Each new feature or task is developed on a dedicated branch, separate from the main development branch (often referred to as "master" or "main").&lt;br&gt;
Developers create a new branch for each feature they are working on, based on the main branch.&lt;br&gt;
This approach allows for parallel development as team members can work independently on their assigned resources.&lt;br&gt;
Once a feature is completed, the branch is merged back into the development branch, usually via a pull request.&lt;br&gt;
Pull requests provide an opportunity for code review, ensuring the quality and integrity of the code base.&lt;br&gt;
Feature Branch Workflow promotes resource isolation, simplifies collaboration, and facilitates change tracking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Release flow:&lt;/strong&gt;&lt;br&gt;
Flow builds on the Feature Branch Workflow and incorporates separate branches for Tags and Hotfixes. This flow offers a more structured approach to branching:&lt;br&gt;
The Flow involves two main branches: "develop" and "master" (or "main").&lt;br&gt;
The "develop" branch serves as the main integration branch, where ongoing development and feature integration takes place.&lt;br&gt;
When a set of features is ready for release, I recommend using The &lt;a href="https://dev.to/brunosouzas/demystifying-the-maven-release-prepare-plugin-streamlining-software-releases-2ge8"&gt;maven release:prepare&lt;/a&gt; to goal prepares the project for release by updating the version, creating SCM tags, and performing various checks.&lt;br&gt;
The "master"/"main" branch and release tag contain the stable, production-ready code.&lt;br&gt;
If critical issues arise in the production environment, hotfix branches are created from "master"/"main", addressing the issue and merging it immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The SNAPSHOT Strategy:&lt;/strong&gt;&lt;br&gt;
A snapshot version in Maven is one that has not been released.&lt;br&gt;
The idea is that before a 1.0 release (or any other release) is made, there is a 1.0-SNAPSHOT. That version is what 1.0 might become. It's basically "1.0 in development".&lt;br&gt;
The difference between a "real" version and a snapshot version is that snapshots can receive updates, that is, you can make changes to the same version and deploy it as many times as necessary.&lt;br&gt;
Typically, snapshot dependencies should only exist during development, and no released versions should have a dependency on a snapshot version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
A well-defined git branch strategy is essential for effective collaboration, parallel development, and maintaining a stable codebase. Feature Branch Workflow allows developers to work on features independently, facilitating collaboration through pull requests. On the other hand, Release Stream offers a more structured approach, incorporating Tag and hotfix to manage software releases effectively. Choosing the right branch strategy depends on the specific needs of your team and the complexity of the project.&lt;/p&gt;

&lt;p&gt;By adopting a proper git branch strategy and leveraging the powerful features of Git, development teams can streamline their workflows, improve collaboration, and efficiently deliver high-quality software.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Demystifying the Maven Release Prepare Plugin: Streamlining Software Releases</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Mon, 12 Jun 2023 08:15:54 +0000</pubDate>
      <link>https://dev.to/brunosouzas/demystifying-the-maven-release-prepare-plugin-streamlining-software-releases-2ge8</link>
      <guid>https://dev.to/brunosouzas/demystifying-the-maven-release-prepare-plugin-streamlining-software-releases-2ge8</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;br&gt;
In the world of software development, efficient and seamless release management is crucial for ensuring smooth project deployments. &lt;br&gt;
Maven, a popular build automation tool, offers the Maven Release Prepare Plugin as a powerful solution to simplify and automate the release process. In this blog post, we'll dive into the Maven Release Prepare Plugin, exploring its key features and demonstrating how it can streamline software releases.&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%2Fz3dew8mxirxahkt0th0q.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%2Fz3dew8mxirxahkt0th0q.png" alt="maven release"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://maven.apache.org/maven-release/maven-release-plugin/prepare-mojo.html" rel="noopener noreferrer"&gt;maven-release-plugin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Understanding the Maven Release Prepare Plugin:&lt;/strong&gt;&lt;br&gt;
The Maven Release Prepare Plugin is designed to assist developers in managing the release lifecycle of their projects. It automates various tasks like version updates, SCM tagging, and generating release documentation. By following a well-defined process, this plugin helps maintain consistency and ensures that releases are controlled and repeatable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Getting Started with the Plugin:&lt;/strong&gt;&lt;br&gt;
To begin using the Maven Release Prepare Plugin, you need to configure it in your project's pom.xml file. By specifying the plugin's coordinates and defining its goals, you can customize its behaviour according to your specific requirements. Additionally, it's important to have a well-structured versioning scheme in place to facilitate smooth release management.&lt;/p&gt;

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

&amp;lt;version&amp;gt;**1.0.0-SNAPSHOT**&amp;lt;/version&amp;gt;

&amp;lt;scm&amp;gt;
  &amp;lt;connection&amp;gt;scm:git:${scm.ssh}&amp;lt;/connection&amp;gt;
  &amp;lt;url&amp;gt;${scm.https}&amp;lt;/url&amp;gt;
  &amp;lt;developerConnection&amp;gt;scm:git:${scm.ssh}&amp;lt;/developerConnection&amp;gt;
&amp;lt;/scm&amp;gt;

&amp;lt;build&amp;gt;
  &amp;lt;plugins&amp;gt;
    &amp;lt;plugin&amp;gt;
      &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;maven-release-plugin&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;3.0.0&amp;lt;/version&amp;gt;
      &amp;lt;configuration&amp;gt;
        &amp;lt;serverId&amp;gt;github-ssh&amp;lt;/serverId&amp;gt;
        &amp;lt;tagNameFormat&amp;gt;v-@{project.version}&amp;lt;/tagNameFormat&amp;gt;
        &amp;lt;checkModificationExcludes&amp;gt;
          &amp;lt;checkModificationExclude&amp;gt;pom.xml&amp;lt;/checkModificationExclude&amp;gt;          
        &amp;lt;/checkModificationExcludes&amp;gt;
      &amp;lt;/configuration&amp;gt;
    &amp;lt;/plugin&amp;gt;
  &amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;${scm.ssh} = &lt;a href="mailto:git@github.com"&gt;git@github.com&lt;/a&gt;:[ORG]/[PROJECT].git&lt;br&gt;
${scm.https} = &lt;a href="https://github.com/%5BORG%5D/%5BPROJECT%5D.git" rel="noopener noreferrer"&gt;https://github.com/[ORG]/[PROJECT].git&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For SSH Authentication add in your settings.xml&lt;/p&gt;

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

&amp;lt;server&amp;gt;
  &amp;lt;id&amp;gt;github-ssh&amp;lt;/id&amp;gt;
  &amp;lt;privateKey&amp;gt;~/.ssh/github_brunosouzas&amp;lt;/privateKey&amp;gt;
  &amp;lt;passphrase&amp;gt;123456&amp;lt;/passphrase&amp;gt;
&amp;lt;/server&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent" rel="noopener noreferrer"&gt;generate SSH&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Performing a Release:&lt;/strong&gt;&lt;br&gt;
When you're ready to create a release, the Maven Release Prepare Plugin provides a set of goals to guide you through the process. These goals include &lt;strong&gt;release:prepare&lt;/strong&gt;, and &lt;strong&gt;release:rollback&lt;/strong&gt;. The release:prepare goal prepares the project for release, update the version, create SCM tags, and verify that all prerequisites are met. The release:rollback goal reverts the release changes if necessary.&lt;/p&gt;

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

mvn release:prepare
mvn release:rollback


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;4. Result:&lt;/strong&gt;&lt;br&gt;
After running that command you'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A tag &lt;strong&gt;v-1.0.0&lt;/strong&gt; in tag session&lt;/li&gt;
&lt;li&gt;The last commit of the branch where you executed the command will have version &lt;strong&gt;1.0.0&lt;/strong&gt; in the pom.xml and the commit message "[maven-release-plugin] prepare release v-1.0.0"&lt;/li&gt;
&lt;li&gt;The branch where you executed the command will have version &lt;strong&gt;1.0.1-SNAPSHOT&lt;/strong&gt; in the pom.xml and the commit message "[maven-release-plugin] prepare for next development iteration"&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The commit message can help you in your deploy process with CI/CD tools&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;5. Fine-Tuning the Release Process:&lt;/strong&gt;&lt;br&gt;
The Maven Release Prepare Plugin offers several configuration options to tailor the release process to your specific needs. You can define additional SCM settings, configure the release versioning scheme, and customize the release goals' behaviour. Furthermore, the plugin allows you to specify additional steps or execute custom scripts during the release process, granting you greater flexibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
The Maven Release Prepare Plugin is a powerful tool that simplifies and automates the release management process in Maven-based projects. The plugin ensures consistent and controlled releases by providing a structured approach to versioning, SCM tagging, and release documentation.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deploying MuleSoft Application to Cloudhub 2.0 using Azure DevOps - Part 2</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Wed, 15 Mar 2023 07:45:27 +0000</pubDate>
      <link>https://dev.to/brunosouzas/deploying-mulesoft-application-to-cloudhub-20-using-azure-devops-part-2-4n7p</link>
      <guid>https://dev.to/brunosouzas/deploying-mulesoft-application-to-cloudhub-20-using-azure-devops-part-2-4n7p</guid>
      <description>&lt;p&gt;This article is the continuation from &lt;a href="https://dev.to/brunosouzas/deploying-mulesoft-application-to-cloudhub-20-using-azure-devops-part-1-2h4d"&gt;&lt;strong&gt;Deploying MuleSoft Application to Cloudhub 2.0 using Azure DevOps - Part 1&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
Now we talk about how to deploy a MuleSoft Application to Production environment with approvers.&lt;/p&gt;

&lt;p&gt;Just to remember you, here is the deploy process&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%2Fbbadx8g41gc16ch906kr.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%2Fbbadx8g41gc16ch906kr.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We did the steps to develop and now we will use the artifact created in develop step and deploy in production environment.&lt;br&gt;
you will need to update the &lt;a href="https://github.com/brunosouzas/devops-scripts.git" rel="noopener noreferrer"&gt;devops-scripts&lt;/a&gt; repository to have the scripts we will be using in the steps below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Import the Release Pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate to Pipeline / Releases and click in Import release pipeline&lt;br&gt;
The template is in your repository devops-scripts/common/template-release-pipeline.json to import&lt;br&gt;
To reuse the template import and clone the pipeline to new projects.&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%2Fbtqjvhla39pfhjo7jopx.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%2Fbtqjvhla39pfhjo7jopx.png" alt="Azure Devops"&gt;&lt;/a&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%2Fksn7fw2r0ap049fvdf47.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%2Fksn7fw2r0ap049fvdf47.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Change the Release Pipeline Name to &lt;strong&gt;hello-world&lt;/strong&gt;&lt;br&gt;
Click in _artifacts and delete&lt;br&gt;
Add a new Artifacts like example below&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%2Fzkgrvkvygybeee8jo00v.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%2Fzkgrvkvygybeee8jo00v.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Type: Build&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Project:&lt;/strong&gt; Add the Azure Project when have the application repository&lt;br&gt;
&lt;strong&gt;Source (build pipeline):&lt;/strong&gt; Select the MuleSoft Application (hello-world)&lt;br&gt;
&lt;strong&gt;Default version:&lt;/strong&gt; Specify at the time of release creation&lt;br&gt;
&lt;strong&gt;Source Alias:&lt;/strong&gt; _artifact&lt;/p&gt;

&lt;p&gt;Click in _develop-scripts and delete&lt;br&gt;
Add a new Artifacts like example below&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%2Flxp95oo1l9p1xy6xm4ay.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%2Flxp95oo1l9p1xy6xm4ay.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Type: Azure Repository&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Project:&lt;/strong&gt; Mulesoft-Project&lt;br&gt;
&lt;strong&gt;Source (repository):&lt;/strong&gt; devops-scripts&lt;br&gt;
&lt;strong&gt;Default branch:&lt;/strong&gt; main&lt;br&gt;
&lt;strong&gt;Default version:&lt;/strong&gt; Latest from the default branch&lt;br&gt;
&lt;strong&gt;Source Alias:&lt;/strong&gt; _devops-scripts&lt;/p&gt;

&lt;p&gt;Add Approvers to Deploy in Production&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%2Ff01z66tgjkkzy7ielgvo.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%2Ff01z66tgjkkzy7ielgvo.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click in the Task&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%2F8fkjx4y1lxbhje106ji0.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%2F8fkjx4y1lxbhje106ji0.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click in Job to Select the Agent Pool (MacOS/Linux)&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%2Fuv0282za6pgeedy1absb.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%2Fuv0282za6pgeedy1absb.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the settings.xml&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%2Fs3b2bsojln61capdk811.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%2Fs3b2bsojln61capdk811.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Link the variable groups&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%2Fvqprvqfelx301q3dxj1x.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%2Fvqprvqfelx301q3dxj1x.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;anypoint-platform-variables&lt;/strong&gt; : Scopes - Release&lt;br&gt;
&lt;strong&gt;anypoint-platform-&amp;lt;ENVIRONMENT&amp;gt;-variables&lt;/strong&gt; : Select the Scope to Specific Environment&lt;br&gt;
&lt;strong&gt;&amp;lt;APPLICATION NAME&amp;gt;&lt;/strong&gt; : Scopes – Release&lt;/p&gt;

&lt;p&gt;Continue in Variables and let's create 2 variables&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%2Fsbmuuvlobvfiah73hzgz.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%2Fsbmuuvlobvfiah73hzgz.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ps. You can add this variable in library but the idea is show the options to you learn and improve in your tests.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now Click in Save and create release&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%2Fki96874ui8ffl95r078h.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%2Fki96874ui8ffl95r078h.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose the artifact that you have after deploy in develop (pipeline)&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%2Fh8ja4fvmtnrkfaqg5374.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%2Fh8ja4fvmtnrkfaqg5374.png" alt="Azure Devops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Config Slack/Teams to Azure DevOps
&lt;/h2&gt;

&lt;p&gt;The notification doesn't in scripts, you need config your tools using the links below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/integrations/slack?view=azure-devops" rel="noopener noreferrer"&gt;Slack&lt;/a&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/integrations/microsoft-teams?view=azure-devops" rel="noopener noreferrer"&gt;Microsoft Teams&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We finished the deployment process with these two articles, I believe that now you can have a base to continue studying.&lt;/p&gt;

&lt;p&gt;In the next article I'll talk about parent-pom and how to have specific properties in your project and deploy them without having to add them to the parent-pom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/azure/devops/?view=azure-devops" rel="noopener noreferrer"&gt;Azure-DevOps&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/brunosouzas/deploying-mulesoft-application-to-cloudhub-20-using-azure-devops-part-1-2h4d"&gt;Deploying MuleSoft Application to Cloudhub 2.0 using Azure DevOps - Part 1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Source&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/brunosouzas/devops-scripts" rel="noopener noreferrer"&gt;devops-scripts&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/brunosouzas/mulesoft-hello-world" rel="noopener noreferrer"&gt;MuleSoft hello-world&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mulesoft</category>
      <category>azuredevops</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>Deploying MuleSoft Application to Cloudhub 2.0 using Azure DevOps - Part 1</title>
      <dc:creator>Bruno Souza</dc:creator>
      <pubDate>Wed, 01 Mar 2023 08:35:09 +0000</pubDate>
      <link>https://dev.to/brunosouzas/deploying-mulesoft-application-to-cloudhub-20-using-azure-devops-part-1-2h4d</link>
      <guid>https://dev.to/brunosouzas/deploying-mulesoft-application-to-cloudhub-20-using-azure-devops-part-1-2h4d</guid>
      <description>&lt;p&gt;This article we will talk about how to deploy a MuleSoft Application using Azure DevOps as a CI/CD tool with yaml file as scripts to reuse in any projects.&lt;/p&gt;

&lt;p&gt;We will use Azure Repos as git repository to pipeline scripts and the MuleSoft application.&lt;/p&gt;

&lt;p&gt;I'll split the full process in 2 articles, this article we will explore the deploy to develop environment and the next article we will explore the deploy to production environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure DevOps Project
&lt;/h2&gt;

&lt;p&gt;Create a &lt;a href="https://learn.microsoft.com/en-us/azure/devops/organizations/projects/create-project?view=azure-devops&amp;amp;tabs=browser" rel="noopener noreferrer"&gt;new Project&lt;/a&gt; in Azure DevOps with &lt;strong&gt;mulesoft-projects&lt;/strong&gt; name&lt;/p&gt;

&lt;h2&gt;
  
  
  Importing Script Pipeline
&lt;/h2&gt;

&lt;p&gt;After create your project in Azure DevOps, we need import the &lt;a href="https://github.com/brunosouzas/devops-scripts.git" rel="noopener noreferrer"&gt;devops-scripts&lt;/a&gt; to &lt;a href="https://learn.microsoft.com/en-us/azure/devops/repos/git/import-git-repository?source=recommendations&amp;amp;view=azure-devops" rel="noopener noreferrer"&gt;azure repos&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ps. Use the &lt;strong&gt;devops-scripts&lt;/strong&gt; as repo name with &lt;strong&gt;main&lt;/strong&gt; branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Azure DevOps Configuration
&lt;/h2&gt;

&lt;p&gt;Now we will create the variables, you can navigate to Pipeline menu in your project and click on &lt;strong&gt;Library&lt;/strong&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%2Fnkwfvz2bwc5mwpr7pooj.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%2Fnkwfvz2bwc5mwpr7pooj.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Variable Groups
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops&amp;amp;tabs=yaml" rel="noopener noreferrer"&gt;Variable Groups&lt;/a&gt; are frequently used to store values that are desirable to make available across the pipelines. Additionally, they can be used to store secrets and credentials that are going to be needed into our build and release pipelines. We are going to create the following variable groups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;anypoint-platform-variables&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AnypointClientId - Specifies the Connected App clientID value&lt;/li&gt;
&lt;li&gt;AnypointClientSecret - Specifies the Connected App secret key.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;anypoint-platform-&amp;lt;ENVIRONMENT&amp;gt;-variables&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chEnv - Specifies the Cloudhub Environment Name&lt;/li&gt;
&lt;li&gt;muleEnv - Specifies the Mule Environment used in your project&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&amp;lt;APPLICATION NAME&amp;gt;&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;encryptKey - encrypt key for production&lt;/li&gt;
&lt;li&gt;encryptKeyNonProd - encrypt key for non-production&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This variable is used to add common passwords used in all application, if you have to use dynamic properties, we'll talk about in another article how to add dynamic properties with parent-pom.&lt;/em&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%2F4e91hyd846waebkn8feh.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%2F4e91hyd846waebkn8feh.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Connected App
&lt;/h3&gt;

&lt;p&gt;Click &lt;a href="https://docs.mulesoft.com/access-management/connected-apps-developers#create-a-connected-app" rel="noopener noreferrer"&gt;here&lt;/a&gt; to learn how to create a Connected App at Anypoint Platform.&lt;/p&gt;

&lt;p&gt;This is the scopes you need add to deploy process&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Runtime Manager&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create Applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read Applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;General&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View Environment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View Organization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exchange&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exchange Contributor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exchange Viewer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Secure Files
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=azure-devops" rel="noopener noreferrer"&gt;Secure Files&lt;/a&gt; can be used to encrypt valuable resources that will be needed during the build and release pipelines.&lt;/p&gt;

&lt;p&gt;The Maven &lt;strong&gt;settings.xml&lt;/strong&gt; file containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MuleSoft Enterprise Repository Nexus Credentials.&lt;/li&gt;
&lt;li&gt;Connected APP to deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In devops-script repository has a template into /common folder&lt;/p&gt;

&lt;p&gt;Add the &lt;strong&gt;settings.xml&lt;/strong&gt; in secure file to be use in deploy process.&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%2Fftetb74vpatzjeo4gcs1.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%2Fftetb74vpatzjeo4gcs1.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment Steps
&lt;/h3&gt;

&lt;p&gt;The pipeline will be triggered when you do a commit in develop branch, we're testing the code, creating an Artifact to use in Production deploy and do the deploy to develop environment.&lt;/p&gt;

&lt;p&gt;The Release Pipeline is a manual process to deploy in production environment using the artifact created in develop steps with approvers.&lt;/p&gt;

&lt;p&gt;The diagram below illustrates the concept:&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%2Fvs36yb4fa0hy7h4ttseo.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%2Fvs36yb4fa0hy7h4ttseo.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Scripts
&lt;/h3&gt;

&lt;p&gt;We have 2 main scripts in our process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;azure-pipelines.yml&lt;/li&gt;
&lt;li&gt;mulesoft-jobs.yml&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The script &lt;strong&gt;azure-pipeline.yml&lt;/strong&gt; is in raw folder from MuleSoft application and contains the minimal configuration to start the process.&lt;/p&gt;

&lt;p&gt;The script &lt;strong&gt;mulesoft-jobs.yml&lt;/strong&gt; is in devops-scripts repository, is the common script with the steps of the deploy process.&lt;/p&gt;

&lt;h2&gt;
  
  
  MuleSoft Application
&lt;/h2&gt;

&lt;p&gt;To this example you will import this &lt;a href="https://github.com/brunosouzas/mulesoft-hello-world.git" rel="noopener noreferrer"&gt;example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I project you have 2 important files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;azure-pipelines.yml&lt;/li&gt;
&lt;li&gt;pom.xml&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Azure-pipelines.yml
&lt;/h3&gt;

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

name: $(Date:yyyyMMdd).$(Rev:r)
resources:
  repositories:
  - repository: devops-scripts
    type: git
    name: mulesoft-projects/devops-scripts
    ref: refs/heads/main

trigger:
- develop
- release-\*

stages:
- template: mulesoft-jobs.yml@devops-scripts


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Name&lt;/strong&gt; : This is the code you see every time you run the pipeline&lt;br&gt;
&lt;strong&gt;Resources/Repositories&lt;/strong&gt; : The repository used to call the template in stage&lt;br&gt;
&lt;strong&gt;Trigger&lt;/strong&gt; : the branches that will trigger&lt;br&gt;
&lt;strong&gt;Stages/Template&lt;/strong&gt; : main script yaml from process&lt;/p&gt;

&lt;h3&gt;
  
  
  Pom.xml
&lt;/h3&gt;

&lt;p&gt;The configuration to deploy in Cloudhub&lt;/p&gt;

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

&amp;lt;cloudhub2Deployment&amp;gt;
…
&amp;lt;/cloudhub2Deployment&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The config to deploy in Anypoint Exchange&lt;/p&gt;

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

&amp;lt;distributionManagement&amp;gt;
…
&amp;lt;/distributionManagement&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you need more details about deploy config using maven, click &lt;a href="https://docs.mulesoft.com/mule-runtime/4.4/deploy-to-cloudhub-2" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Pipeline to your Application
&lt;/h2&gt;

&lt;p&gt;Go to Pipelines and click in New Pipeline &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%2Fpk3hzfrr9howss7hh5io.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%2Fpk3hzfrr9howss7hh5io.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose Azure Repos Git (YAML)&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%2Fb7fr1b14e6a8ter9d04c.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%2Fb7fr1b14e6a8ter9d04c.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose the Mule Application Repository (hello-world)&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%2Fsn7lgfb3vnotuby3nx50.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%2Fsn7lgfb3vnotuby3nx50.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see the azure-pipelines.yml, Click in Save&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%2F8qmia3qqdpatpdnqinbq.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%2F8qmia3qqdpatpdnqinbq.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can Run the Pipeline (use develop branch, the script has a rule to only deploy develop branch, to production we will use the Release Pipelines)&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%2Fbv43y10995xusn5ohgcx.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%2Fbv43y10995xusn5ohgcx.png" alt="Azure DevOps"&gt;&lt;/a&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%2F6o4rgdptu4hf5rke6uvk.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%2F6o4rgdptu4hf5rke6uvk.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now click in your pipeline to follow the steps and in your first time you need permit the access to Devops-scripts repository and variable group.&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%2Fvdmmlgebxqqlye1kpn5h.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%2Fvdmmlgebxqqlye1kpn5h.png" alt="Azure DevOps"&gt;&lt;/a&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%2F9w15k2fwznufh6lyasl5.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%2F9w15k2fwznufh6lyasl5.png" alt="Azure DevOps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Config Slack/Teams to Azure DevOps
&lt;/h2&gt;

&lt;p&gt;The notification doesn't in scripts, you need config your tools using the links below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/integrations/slack?view=azure-devops" rel="noopener noreferrer"&gt;Slack&lt;/a&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/azure/devops/pipelines/integrations/microsoft-teams?view=azure-devops" rel="noopener noreferrer"&gt;Microsoft Teams&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This article does not have the complete deployment process, but the idea is to show how to deploy using the yaml file to reuse in other projects. I tried to use a simple idea using yaml scripts and I believe with this you can study and learn more.&lt;/p&gt;

&lt;p&gt;In yaml script you will see a maven setup script, this script is due a MuleSoft issue with maven 3.9 in this moment (feb-2023).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow" rel="noopener noreferrer"&gt;gitflow-workflow&lt;/a&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/azure/devops/?view=azure-devops" rel="noopener noreferrer"&gt;Azure-DevOps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Source&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/brunosouzas/devops-scripts" rel="noopener noreferrer"&gt;devops-scripts&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/brunosouzas/mulesoft-hello-world" rel="noopener noreferrer"&gt;MuleSoft hello-world&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mulesoft</category>
      <category>azuredevops</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
