{"id":605,"date":"2025-07-02T09:00:00","date_gmt":"2025-07-01T23:00:00","guid":{"rendered":"https:\/\/jm.armijo.au\/dev\/?p=605"},"modified":"2025-07-02T10:31:26","modified_gmt":"2025-07-02T00:31:26","slug":"dependency-inversion-principle","status":"publish","type":"post","link":"https:\/\/jm.armijo.au\/dev\/blog\/2025\/07\/02\/dependency-inversion-principle\/","title":{"rendered":"Dependency Inversion Principle"},"content":{"rendered":"\n<p>In one of my previous articles I made a brief introduction to the SOLID principles for Object Oriented Software Development<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-practical-software-development wp-block-embed-practical-software-development\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"d7O6rsqCTg\"><a href=\"https:\/\/jm.armijo.au\/dev\/blog\/2025\/02\/26\/solid-design-principles-for-object-oriented-software-development\/\">SOLID Design Principles For Object Oriented Software Development<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;SOLID Design Principles For Object Oriented Software Development&#8221; &#8212; Practical Software Development\" src=\"https:\/\/jm.armijo.au\/dev\/blog\/2025\/02\/26\/solid-design-principles-for-object-oriented-software-development\/embed\/#?secret=hvMoNl282x#?secret=d7O6rsqCTg\" data-secret=\"d7O6rsqCTg\" width=\"500\" height=\"282\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>In today\u2019s article, I\u2019d like to cover the Dependency Inversion Principle (DIP) in more depth, starting by explaining what it is, how it&#8217;s supposed to be used, and what are its concrete benefits.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"What-Dependency-Inversion-Is\">What Dependency Inversion Is<\/h3>\n\n\n\n<p>So, let\u2019s consider a house with an old mailbox. We could model that in our code like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; notranslate\" title=\"\">\nclass VintageMailbox {}\n\nclass House {\n  private mailbox = new VintageMailbox();\n}\n\nconst h = new House();\n<\/pre><\/div>\n\n\n<p>In this example, class <code>House<\/code> depends on class <code>Mailbox<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" src=\"https:\/\/documents.lucid.app\/documents\/28c38ec7-4de5-44a5-b38e-47b25b6b7828\/pages\/0_0?a=270&amp;x=356&amp;y=213&amp;w=508&amp;h=141&amp;store=1&amp;accept=image%2F*&amp;auth=LCA%2036b73c6aef427da1b3718c351f1e98adf9d9cf39bce5e8e23c13f16aa69887c2-ts%3D1751415719\" alt=\"\" style=\"width:373px;height:auto\" \/><\/figure>\n\n\n\n<p>This is the most common way of writing classes, because it is really easy to just create the new instance of our class where we need it.<\/p>\n\n\n\n<p>The Dependency Inversion principle proposes that, instead of depending on concrete instances, we should depend on abstractions, like an interface or an abstract class. We can achieve that by using Dependency Injection:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\ninterface Mailbox {}\nclass VintageMailbox implements Mailbox {}\n\nclass House {\n  constructor(private mailbox: Mailbox) {}\n}\n\nconst mailbox: VintageMailbox = new VintageMailbox();\nconst house = new House(mailbox);\n<\/pre><\/div>\n\n\n<p>In this updated example, class <code>House<\/code> expects any class that implements <code>Mailbox<\/code>. This is possible with the introduction of the <code>Mailbox<\/code> interface, making classes <code>VintageMailbox<\/code> and <code>House<\/code> depend on it.<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" src=\"https:\/\/documents.lucid.app\/documents\/28c38ec7-4de5-44a5-b38e-47b25b6b7828\/pages\/0_0?a=314&amp;x=467&amp;y=461&amp;w=706&amp;h=405&amp;store=1&amp;accept=image%2F*&amp;auth=LCA%20d833d844c1f69ee2d38a31bae6c716d4d9f5e7b315462593efcba4f74243d7a1-ts%3D1751415719\" alt=\"\" style=\"width:498px;height:auto\" \/><\/figure>\n\n\n\n<p>In non-typed languages like Ruby, there are no interfaces, but we can still apply the same idea by relying on shared behaviour.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: ruby; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nclass VintageMailbox\nend\n\nclass House\n  def initialize(mailbox)\n    @mailbox = mailbox\n  end\nend\n\nmailbox = VintageMailbox.new\nhouse = House.new(mailbox)\n<\/pre><\/div>\n\n\n<p>Here, <code>House<\/code> doesn\u2019t care what <code>mailbox<\/code> is, as long as it responds to the methods <code>House<\/code> needs. That means we can pass in any object with the right methods, and <code>House<\/code> will work without knowing its exact class. This is dependency inversion in a duck-typed way.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"How-to-set-it-up\">How to set it up<\/h3>\n\n\n\n<p>The code above is the typical example of the Dependency Inversion Principle, but it doesn\u2019t show how to use it in a real project.<\/p>\n\n\n\n<p>To better show this, let\u2019s consider three layers of dependency: a house has a mailbox, and a mailbox has a lock. The code below shows what it looks like when we don\u2019t follow the Dependency Inversion Principle. First, we\u2019ll start by ensuring that we have all our dependencies:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\n\/\/ padlock.ts\nclass Padlock {}\n\n\/\/ smartLock.ts\nclass SmartLock {}\n\n\/\/ vintageMailbox.ts\nclass VintageMailbox {\n  private lock = new Padlock();\n}\n\n\/\/ modernMailbox.ts\nclass ModernMailbox {\n  private lock = new SmartLock();\n}\n<\/pre><\/div>\n\n\n<p>It\u2019s worth a closer look at the House class, since this is where we put the logic to choose which mailbox to use:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\n\/\/ house.ts\nclass House {\n  private mailbox;\n\n  constructor(type: &quot;vintage&quot; | &quot;modern&quot;) {\n    if (type === &quot;modern&quot;) {\n      this.mailbox = new ModernMailbox();\n    } else {\n      this.mailbox = new VintageMailbox();\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<p>And finally, we just create our instances of <code>House<\/code> in our <code>main.ts<\/code> file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\n\/\/ main.ts\nconst house1 = new House(&quot;vintage&quot;);\nconst house2 = new House(&quot;modern&quot;);\n<\/pre><\/div>\n\n\n<p>In order to follow the Dependency Inversion Principle, we still need to create specific Mailbox and Lock classes, just not inside other classes. Like before, we\u2019ll start by creating our dependencies. Note how, in this case, they don\u2019t depend on specific classes, but only on the new interfaces that we also created here:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\n\/\/ lock.ts\ninterface Lock {}\n\n\/\/ padlock.ts\nclass Padlock implements Lock {}\n\n\/\/ smartLock.ts\nclass SmartLock implements Lock {}\n\n\/\/ mailbox.ts\ninterface Mailbox {}\n\n\/\/ vintageMailbox.ts\nclass VintageMailbox implements Mailbox {\n  constructor(private lock: Lock) {}\n}\n\n\/\/ modernMailbox.ts\nclass ModernMailbox implements Mailbox {\n  constructor(private lock: Lock) {}\n}\n<\/pre><\/div>\n\n\n<p>Now our <code>House<\/code> class becomes really simple, as it doesn\u2019t need to know anything about specific Mailbox types:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\n\/\/ house.ts\nclass House {\n  constructor(private mailbox: Mailbox) {}\n}\n<\/pre><\/div>\n\n\n<p>And finally, we specify the concrete class instances that we\u2019ll need close to our system\u2019s entry point, which corresponds to <code>main.ts<\/code> in this case:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\n\/\/ main.ts\nconst house1 = new House(new VintageMailbox(new Padlock()));\nconst house2 = new House(new ModernMailbox(new SmartLock()));\n<\/pre><\/div>\n\n\n<p>Having covered what dependency inversion is and how we can implement it, let\u2019s see why we should bother.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Why-Dependency-Inversion-Matters\">Why Dependency Inversion Matters<\/h3>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"System-configuration\">System configuration<\/h5>\n\n\n\n<p>In the previous section we saw how simple our code becomes when we decide what concrete classes to use at the top of the system rather than buried deep in the code.<\/p>\n\n\n\n<p>I must admit that, when I first learnt this concept, I was really confused for two reasons: I thought that making changes at the top level was still a violation of the Open-Closed Principle; and I could not see why defining the low-level dependencies at the top level would help.<\/p>\n\n\n\n<p>After reading a lot on the topic and also talking to several colleagues, I managed to solve the apparent paradox and understand the value of this.<\/p>\n\n\n\n<p>First, if we want to change how our system behaves, we\u2019ll have to change our systems somewhere. The Open Closed Principle, which deserves an article for itself, is not about not changing our code at all, but about being smart about what we change and where.<\/p>\n\n\n\n<p>Secondly, it helps explain why it\u2019s actually a good idea to move all these low-level dependencies to the top level. Instead of creating classes deep inside our code, we can do that near the system\u2019s entry point using things like factories, builders, or even configuration files to decide what to use.<\/p>\n\n\n\n<p>For example, we could create this configuration file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\n{\n  &quot;mailbox_type&quot;: &quot;ModernMailbox&quot;\n}\n<\/pre><\/div>\n\n\n<p>And read the classes to create like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: ruby; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nclass VintageMailbox; end\n\nclass ModernMailbox; end\n\nclass House\n  def initialize(mailbox)\n    @mailbox = mailbox\n  end\nend\n\nconfig = JSON.parse(File.read('config.json'))\nmailbox_class_name = config&#x5B;&quot;mailbox_type&quot;]\n\nmailbox = Object.const_get(mailbox_class_name).new\nhouse = House.new(mailbox)\n<\/pre><\/div>\n\n\n<p>The complexity of deciding what specific classes we\u2019re using has been moved to a single place at the top of our system. This means that, if we need to change the type of lock to be used in a house with a vintage mailbox, we just need to change our initial setup, while the rest of our code can be left unchanged.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"Code-extension\">Code extension<\/h5>\n\n\n\n<p>When we follow the Dependency Inversion principle, we can extend our codebase without changing the classes that implement our business logic. For example, imagine that we want to change class <code>VintageMailbox<\/code> with <code>ModernMailbox<\/code>. A simple approach would be to just do the changes in <code>VintageMailbox<\/code>, or we could create a new class to represent a <code>ModernMailbox<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nclass VintageMailbox {}\nclass ModernMailbox {}\n\nclass House {\n  private mailbox = new ModernMailbox();\n}\n\nconst h = new House();\n<\/pre><\/div>\n\n\n<p>Unfortunately, both alternatives go directly against the Open-Closed principle. If instead we use Dependency Inversion, we can create the new <code>ModernMailbox<\/code> class and pass an instance to class <code>House<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\ninterface Mailbox {}\nclass VintageMailbox implements Mailbox {}\nclass ModernMailbox implements Mailbox {}\n\nclass House {\n  constructor(private mailbox: Mailbox) {}\n}\n\nconst mailbox: ModernMailbox = {};\nconst house = new House(mailbox);\n<\/pre><\/div>\n\n\n<p>In this example, we don&#8217;t need to change class <code>House<\/code> if we want to use a different <code>Mailbox<\/code>. By doing this, we are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Making code <strong>extensible without modification<\/strong><\/li>\n\n\n\n<li>Avoiding <strong>fragile base classes<\/strong><\/li>\n\n\n\n<li>Protecting existing behaviour when adding new features<\/li>\n<\/ul>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"Code-reuse\">Code reuse<\/h5>\n\n\n\n<p>Let\u2019s review again the original implementation of the <code>House<\/code> class.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nclass VintageMailbox {}\n\nclass House {\n  private mailbox = new VintageMailbox();\n}\n\nconst h = new House();\n<\/pre><\/div>\n\n\n<p>Now, imagine that we want to create two houses, the first with a <code>VintageMailbox<\/code>, and the second with a <code>ModernMailbox<\/code>. One option that makes my eyes bleed is to duplicate our class House:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nclass VintageMailbox {}\n\nclass VintageHouse {\n  private mailbox = new VintageMailbox();\n}\n\nclass ModernHouse {\n  private mailbox = new ModernMailbox();\n}\n\nconst house1 = new VintageHouse();\nconst house2 = new ModernHouse();\n<\/pre><\/div>\n\n\n<p>Another option that is not any better is to add a variable to specify the type of Mailbox that we need, but this again violates the Open-Closed Principle:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nclass VintageMailbox {}\nclass ModernMailbox {}\n\nclass House {\n  private mailbox;\n\n  constructor(type: &quot;vintage&quot; | &quot;modern&quot;) {\n    if (type === &quot;modern&quot;) {\n      this.mailbox = new ModernMailbox();\n    } else {\n      this.mailbox = new VintageMailbox();\n    }\n  }\n}\n\nconst house1 = new House(&quot;vintage&quot;);\nconst house2 = new House(&quot;modern&quot;);\n<\/pre><\/div>\n\n\n<p>When we depend on concrete classes, our code becomes too rigid and there is no way to extend it without either duplicating or changing code.<\/p>\n\n\n\n<p>Instead, when we follow the Dependency Inversion Principle, we can create houses with different types of <code>Mailbox<\/code> classes, even those we have not even thought of yet, without having to change how class <code>House<\/code> works or uses the instances of class <code>Mailbox<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\ninterface Mailbox {}\nclass VintageMailbox implements Mailbox {}\nclass ModernMailbox implements Mailbox {}\nclass FuturisticMailbox implements Mailbox {}\n\nclass House {\n  constructor(private mailbox: Mailbox) {}\n}\n\nconst house1 = new House(new VintageMailbox());\nconst house2 = new House(new ModernMailbox());\nconst house3 = new House(new FuturisticMailbox());\n<\/pre><\/div>\n\n\n<h5 class=\"wp-block-heading\" id=\"Easier-testing\">Easier testing<\/h5>\n\n\n\n<p>Let\u2019s consider our original example once more:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nclass VintageMailbox {}\n\nclass House {\n  private mailbox = new VintageMailbox();\n}\n\nconst h = new House();\n<\/pre><\/div>\n\n\n<p>If we want to unit test class <code>House<\/code> we\u2019ll probably want to test it independently of class <code>VintageMailbox<\/code>. Something like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\njest.mock('.\/vintageMailbox', () =&gt; {\n  return {\n    VintageMailbox: jest.fn(), \/\/ mock constructor\n  };\n});\n\ntest('House uses mocked VintageMailbox', () =&gt; {\n  (VintageMailbox as jest.Mock).mockImplementation(() =&gt; ({\n    deliver: jest.fn(),\n  }));\n\n  const house = new House();\n\n  expect(VintageMailbox).toHaveBeenCalled();\n});\n<\/pre><\/div>\n\n\n<p>While working with Typescript I\u2019ve sometimes felt like a wizard pulling up a trick when trying to mock something. And when it works, the code is not nice, and it\u2019s usually left alone as just looking at it may break it.<\/p>\n\n\n\n<p>If instead we use dependency inversion:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\ninterface Mailbox {}\n\nclass VintageMailbox implements Mailbox {}\n\nclass House {\n  constructor(private mailbox: Mailbox) {}\n}\n\nconst mailbox: VintageMailbox = new VintageMailbox();\nconst house = new House(mailbox);\n<\/pre><\/div>\n\n\n<p>We can just create a simple testing class with the logic we need, without relying on mocks.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: jscript; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nclass TestingMailbox implements Mailbox {}\n\ntest('House uses mocked VintageMailbox', () =&gt; {\n  const mailbox = new TestingMailbox()\n  const house = new House(mailbox);\n\n  expect(mailbox).toHaveBeenCalled();\n});\n<\/pre><\/div>\n\n\n<p>When I write unit tests in Ruby using Rspec I prefer to use doubles instead of creating testing classes, as they are quite powerful and easy to create. And then, I just pass the double to the class being tested:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: ruby; auto-links: false; gutter: false; title: ; quick-code: false; notranslate\" title=\"\">\nRSpec.describe House do\n  it 'uses a mocked mailbox' do\n    mailbox = double('VintageMailbox')\n\n    house = House.new(mailbox)\n\n    expect(house).to be_a(House)\n  end\nend\n<\/pre><\/div>\n\n\n<p>As a result, when following the Dependency Inversion Principle, unit testing becomes extremely easy and produces cleaner test code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Final thoughts<\/h3>\n\n\n\n<p>In this article, we saw what the Dependency Inversion Principle is and how to set it up, which will hopefully remove any worries about it being too complex. We also looked at the real benefits it brings: simpler code, easier testing, and better flexibility.<\/p>\n\n\n\n<p>However, it\u2019s important to be mindful of the context we\u2019re working in, and not rush to change everything just to follow the principle. Like with anything in software, context matters. This is a great tool to have in our arsenal, but we should avoid premature optimisations and think carefully about when it actually makes sense to apply it.<\/p>\n\n\n\n<p>Happy coding!<br>Jos\u00e9 Miguel<\/p>\n\n\n\n<p><em>Share if you find this content useful.<\/em><br><em>Follow me on&nbsp;<a href=\"http:\/\/www.linkedin.com\/comm\/mynetwork\/discovery-see-all?usecase=PEOPLE_FOLLOWS&amp;followMember=jmarmijo\">LinkedIn<\/a>&nbsp;to be notified of new articles.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In one of my previous articles I made a brief introduction to the SOLID principles for Object Oriented Software Development In today\u2019s article, I\u2019d like to cover the Dependency Inversion Principle (DIP) in more depth, starting by explaining what it is, how it&#8217;s supposed to be used, and what are its concrete benefits. What Dependency [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":619,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-605","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/posts\/605","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/comments?post=605"}],"version-history":[{"count":15,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/posts\/605\/revisions"}],"predecessor-version":[{"id":623,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/posts\/605\/revisions\/623"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/media\/619"}],"wp:attachment":[{"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/media?parent=605"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/categories?post=605"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jm.armijo.au\/dev\/wp-json\/wp\/v2\/tags?post=605"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}