{"id":155,"date":"2019-12-16T14:54:13","date_gmt":"2019-12-16T14:54:13","guid":{"rendered":"https:\/\/blog.adonlon.org\/?p=155"},"modified":"2019-12-17T14:46:04","modified_gmt":"2019-12-17T14:46:04","slug":"refined-types-in-domain-driven-design","status":"publish","type":"post","link":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/","title":{"rendered":"Refined Types in Domain Driven Design"},"content":{"rendered":"\n<p>In a world of domain driven design we like to use lots of types. In particular, we use a lot of value types, and we will even choose to create a type which is little more than a wrapper for a single value of an underlying type. Often the set of valid values of the new type is not much more than a strict subset of the set of valid values of the underlying type.<\/p>\n\n\n\n<p>There&#8217;s a number of benefits of this approach. Very simply, it helps to read and reason about the code and it highlights the core domain logic. A more complex benefit is that it makes the logic more testable by isolating handling of edge cases to those parts of the code which are most closely associated with the definition of that type.<\/p>\n\n\n\n<p>As an example, we might look at a port number. Variables holding port numbers are often just modelled as an integral type, such as <code>Int<\/code>. But in reality the set of valid port numbers is a much smaller than the set of valid integers. Port numbers can&#8217;t be negative and they can&#8217;t be more than 65355, whereas on the JVM an <code>Int<\/code> can be any value from -2 billion to +2 billion. If we want to really represent the range of port numbers we might prefer to say that a port number is an integer in the range of 0 to 65535 inclusive.<\/p>\n\n\n\n<p>In code this might look like<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">case class PortNumber private (num: Int)\n\nobject PortNumber {\n  def apply(num: Int): Either[String, PortNumber] = num match {\n    case i: Int if i &lt; 0 =&gt; Left(\"Port number may not be negative\")\n    case i: Int if i &gt; 65535 =&gt; Left(\"Port number may not be more than 65535\")\n    case _ =&gt; Right(new PortNumber(num)\n  }\n}<\/pre>\n\n\n\n<p>What we&#8217;ve done here is to encapsulate the case class constructor so that it can&#8217;t be instantiated other than via the companion object&#8217;s <code>apply<\/code> factory method. The <code>apply<\/code> factory then performs some validation, and returns an <code>Either<\/code> containing an error message or a valid value of type <code>PortNumber<\/code>. We also rely on the immutability of case classes to ensure that the underlying value cannot be changed, and the class can&#8217;t be subclassed so there are no complicated inheritance interactions to worry about. Now, anywhere in the rest of the code where a variable of type <code>PortNumber<\/code> appears we can be reasonably sure the the variable contains a valid value.<\/p>\n\n\n\n<p>The cost of the type safety is the complexity associated with writing all these constructors, and chaining their <code>apply<\/code> factory results together to combine multiple value types into more complex value types. There&#8217;s also a slight problem around accessing the underlying value as it&#8217;s now a field within the case class instance rather than being the instance itself. However, this pattern is generally very valuable and so it&#8217;s usually worth the slightly more complex interactions around creating instances of them.<\/p>\n\n\n\n<p>What would be ideal would be a way to create one of these types quickly and easily.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Refined Types<\/h3>\n\n\n\n<p>From the Haskell world we have a concept called Refined Types. Refined types are an implementation of the idea that you can define a new type (e.g. <code>PortNumber<\/code>) as being some kind of &#8216;refinement&#8217; of another type (e.g. <code>Int<\/code>). To define the new type we attach a predicate to the old type which allows us to define the subset of allowed values.<\/p>\n\n\n\n<p>In Scala the <a href=\"https:\/\/github.com\/fthomas\/refined\">refined library<\/a> is an implementation of the Haskell concept. Now we can define our <code>PortNumber<\/code> much more simply&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import eu.timepit.refined.W\nimport eu.timepit.refined.{refineMV, refineV}\nimport eu.timepit.refined.api.Refined\nimport eu.timepit.refined.numeric.Interval\n\ntype PortRange = Interval.Closed[W.0.T, W.65535.T]\ntype PortNumber = Int Refined PortRange\n\nval portValidated: Either[String, PortNumber] = refineV[PortRange](8080)\nval port: PortNumber = refineMV[PortRange](8080)\n<\/pre>\n\n\n\n<p>Here we define our predicate <code>PortRange<\/code> as being a closed interval over all the valid values a port number can have, and then we define <code>PortNumber<\/code> as being a normal <code>Int<\/code> refined using that predicate. The library then gives us two factory methods, paramaterised on predicate, which allow us to construct instances of the refined type. One method produces an <code>Either<\/code> of a error message or the refined value &#8211; good for validating inputs from untrusted sources and handling them safely and cleanly. The other method throws an exception if the input value is invalid &#8211; good for producing values from constants or in test scenarios where data can be trusted and exceptions can be treated as test failures.<\/p>\n\n\n\n<p>Given this basic core infrastructure for creating domain value types, there are a plethora of libraries to help with integrating them with other frameworks or libraries. For example, the <a href=\"https:\/\/github.com\/kwark\/play-refined\">play-refined<\/a> library gives mechanisms to help with conversion to and from values used in controller arguments and to or from JSON.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a world of domain driven design we like to use lots of types. In particular, we use a lot of value types, and we will even choose to create a type which is little more than a wrapper for a single value of an underlying type. Often the set of valid values of the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[11,10,9],"class_list":["post-155","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-domain-driven-design","tag-json","tag-scala"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Refined Types in Domain Driven Design - Pragmatic Software Engineering<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Refined Types in Domain Driven Design - Pragmatic Software Engineering\" \/>\n<meta property=\"og:description\" content=\"In a world of domain driven design we like to use lots of types. In particular, we use a lot of value types, and we will even choose to create a type which is little more than a wrapper for a single value of an underlying type. Often the set of valid values of the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/\" \/>\n<meta property=\"og:site_name\" content=\"Pragmatic Software Engineering\" \/>\n<meta property=\"article:published_time\" content=\"2019-12-16T14:54:13+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-12-17T14:46:04+00:00\" \/>\n<meta name=\"author\" content=\"alastair\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"alastair\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/\"},\"author\":{\"name\":\"alastair\",\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1\"},\"headline\":\"Refined Types in Domain Driven Design\",\"datePublished\":\"2019-12-16T14:54:13+00:00\",\"dateModified\":\"2019-12-17T14:46:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/\"},\"wordCount\":704,\"publisher\":{\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1\"},\"keywords\":[\"Domain Driven Design\",\"Json\",\"Scala\"],\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/\",\"url\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/\",\"name\":\"Refined Types in Domain Driven Design - Pragmatic Software Engineering\",\"isPartOf\":{\"@id\":\"https:\/\/blog.adonlon.org\/#website\"},\"datePublished\":\"2019-12-16T14:54:13+00:00\",\"dateModified\":\"2019-12-17T14:46:04+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.adonlon.org\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Refined Types in Domain Driven Design\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.adonlon.org\/#website\",\"url\":\"https:\/\/blog.adonlon.org\/\",\"name\":\"Pragmatic Software Engineering\",\"description\":\"Random thoughts and insights on software engineering\",\"publisher\":{\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.adonlon.org\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1\",\"name\":\"alastair\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cf9abf1220f449fccd0f6795d12b05cb?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cf9abf1220f449fccd0f6795d12b05cb?s=96&d=mm&r=g\",\"caption\":\"alastair\"},\"logo\":{\"@id\":\"https:\/\/blog.adonlon.org\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Refined Types in Domain Driven Design - Pragmatic Software Engineering","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/","og_locale":"en_GB","og_type":"article","og_title":"Refined Types in Domain Driven Design - Pragmatic Software Engineering","og_description":"In a world of domain driven design we like to use lots of types. In particular, we use a lot of value types, and we will even choose to create a type which is little more than a wrapper for a single value of an underlying type. Often the set of valid values of the [&hellip;]","og_url":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/","og_site_name":"Pragmatic Software Engineering","article_published_time":"2019-12-16T14:54:13+00:00","article_modified_time":"2019-12-17T14:46:04+00:00","author":"alastair","twitter_card":"summary_large_image","twitter_misc":{"Written by":"alastair","Estimated reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/#article","isPartOf":{"@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/"},"author":{"name":"alastair","@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1"},"headline":"Refined Types in Domain Driven Design","datePublished":"2019-12-16T14:54:13+00:00","dateModified":"2019-12-17T14:46:04+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/"},"wordCount":704,"publisher":{"@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1"},"keywords":["Domain Driven Design","Json","Scala"],"articleSection":["Uncategorized"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/","url":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/","name":"Refined Types in Domain Driven Design - Pragmatic Software Engineering","isPartOf":{"@id":"https:\/\/blog.adonlon.org\/#website"},"datePublished":"2019-12-16T14:54:13+00:00","dateModified":"2019-12-17T14:46:04+00:00","breadcrumb":{"@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.adonlon.org\/index.php\/2019\/12\/16\/refined-types-in-domain-driven-design\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.adonlon.org\/"},{"@type":"ListItem","position":2,"name":"Refined Types in Domain Driven Design"}]},{"@type":"WebSite","@id":"https:\/\/blog.adonlon.org\/#website","url":"https:\/\/blog.adonlon.org\/","name":"Pragmatic Software Engineering","description":"Random thoughts and insights on software engineering","publisher":{"@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.adonlon.org\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/4c5a1b2463425db9814bf8540f8954c1","name":"alastair","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cf9abf1220f449fccd0f6795d12b05cb?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cf9abf1220f449fccd0f6795d12b05cb?s=96&d=mm&r=g","caption":"alastair"},"logo":{"@id":"https:\/\/blog.adonlon.org\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/posts\/155","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/comments?post=155"}],"version-history":[{"count":0,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/posts\/155\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/media?parent=155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/categories?post=155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.adonlon.org\/index.php\/wp-json\/wp\/v2\/tags?post=155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}