{"id":2584,"date":"2015-02-19T17:26:31","date_gmt":"2015-02-19T16:26:31","guid":{"rendered":"http:\/\/www.pleus.net\/blog\/?p=2584"},"modified":"2017-08-25T16:40:11","modified_gmt":"2017-08-25T14:40:11","slug":"turn-contracts-into-code","status":"publish","type":"post","link":"https:\/\/www.pleus.net\/blog\/?p=2584","title":{"rendered":"Turn contracts into code"},"content":{"rendered":"<p>Interfaces are one of the most important parts in software design. Designing software around properly defined interfaces has many benefits for instance in the areas of consistency, maintainability and reuse. A well written contract describes precisely how software artefacts (or services) interact with each other. Approaches such as <a title=\"Sustainable Service Design\" href=\"http:\/\/www.pleus.net\/blog\/?p=2546\" target=\"_blank\">Sustainable Service Design<\/a> or the <a title=\"BiPRO\" href=\"http:\/\/www.pleus.net\/blog\/?p=2464\" target=\"_blank\">BiPRO<\/a> standards rely on contracts based on XML Schema (xsd). As they start with the contract design, they are called contract or <a title=\"Schema first\" href=\"http:\/\/www.pleus.net\/blog\/?p=508\" target=\"_blank\">schema first<\/a> approaches.<br \/>\nOnce you have a contract the question is how to turn it into code. In the Java world JAXB is the first choice. Lets&#8217;s see how we can generate Java sourcecode from the schema.<\/p>\n<p>We start with a simple schema shown in the following listing.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;?xml-stylesheet type=&quot;text\/xsl&quot; href=&quot;contract.xsl&quot;?&gt;\r\n&lt;xs:schema\r\n    xmlns:xs=&quot;http:\/\/www.w3.org\/2001\/XMLSchema&quot;\r\n    xmlns:xml=&quot;http:\/\/www.w3.org\/XML\/1998\/namespace&quot;    \r\n    xmlns:service=&quot;http:\/\/www.pleus.net\/services&quot;\r\n    xmlns:tns=&quot;http:\/\/www.pleus.net\/services\/calculator\/api\/model&quot;\r\n\ttargetNamespace=&quot;http:\/\/www.pleus.net\/services\/calculator\/api\/model&quot;\r\n\telementFormDefault=&quot;qualified&quot; attributeFormDefault=&quot;qualified&quot;\r\n\tversion=&quot;1.0&quot;&gt;\r\n\t  \r\n    &lt;!-- ################################################### --&gt;\r\n\t&lt;!-- ################### Messages ###################### --&gt;\r\n    &lt;!-- ################################################### --&gt;\r\n\r\n    \r\n\t&lt;xs:element name=&quot;PerformSimpleCalculationRequest&quot;&gt;\r\n\t\t&lt;xs:annotation&gt;&lt;xs:documentation&gt;Performs a simple calculation&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n\t\t&lt;xs:complexType&gt;\r\n\t\t\t&lt;xs:sequence&gt;\r\n\t\t\t\t&lt;xs:element name=&quot;operation&quot; type=&quot;tns:Operation&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;&gt;\r\n\t\t\t\t\t&lt;xs:annotation&gt;\r\n                        &lt;xs:documentation xml:lang=&quot;EN&quot;&gt;Operation to perform&lt;\/xs:documentation&gt;\r\n                        &lt;xs:documentation xml:lang=&quot;DE&quot;&gt;Operation zur Ausf\u00fchrung&lt;\/xs:documentation&gt;\r\n                    &lt;\/xs:annotation&gt;\r\n\t\t\t\t&lt;\/xs:element&gt;\r\n\t\t\t\t&lt;xs:element name=&quot;value-a&quot; type=&quot;tns:decimal9F2&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;&gt;\r\n\t\t\t\t\t&lt;xs:annotation&gt;&lt;xs:documentation&gt;First value&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n\t\t\t\t&lt;\/xs:element&gt;\r\n\t\t\t\t&lt;xs:element name=&quot;value-b&quot; type=&quot;xs:decimal&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;&gt;\r\n\t\t\t\t\t&lt;xs:annotation&gt;&lt;xs:documentation&gt;Second value&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n\t\t\t\t&lt;\/xs:element&gt;\r\n\t\t\t&lt;\/xs:sequence&gt;\r\n\t\t&lt;\/xs:complexType&gt;\r\n\t&lt;\/xs:element&gt;\r\n    \r\n\t&lt;xs:element name=&quot;PerformSimpleCalculationResponse&quot;&gt;\r\n\t\t&lt;xs:annotation&gt;&lt;xs:documentation&gt;Result of a simple calculation&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n\t\t&lt;xs:complexType&gt;\r\n\t\t\t&lt;xs:sequence&gt;\r\n\t\t\t\t&lt;xs:element name=&quot;result&quot; type=&quot;xs:decimal&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;&gt;\r\n\t\t\t\t\t&lt;xs:annotation&gt;&lt;xs:documentation&gt;Result&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n\t\t\t\t&lt;\/xs:element&gt;\r\n\t\t\t&lt;\/xs:sequence&gt;\r\n\t\t&lt;\/xs:complexType&gt;\r\n\t&lt;\/xs:element&gt;\r\n    \r\n\r\n   &lt;xs:element name=&quot;CalculatorError&quot;&gt;\r\n   \t  &lt;xs:annotation&gt;&lt;xs:documentation&gt;Provides error information&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n      &lt;xs:complexType&gt;\r\n         &lt;xs:sequence&gt;\r\n\t\t\t\t&lt;xs:element name=&quot;message&quot; type=&quot;xs:string&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;&gt;\r\n\t\t\t\t\t&lt;xs:annotation&gt;&lt;xs:documentation&gt;Fehlermeldung&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n\t\t\t\t&lt;\/xs:element&gt;\r\n\t\t\t\t&lt;xs:element name=&quot;code&quot; type=&quot;xs:int&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;&gt;\r\n\t\t\t\t\t&lt;xs:annotation&gt;&lt;xs:documentation&gt;Fehlercode&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n\t\t\t\t&lt;\/xs:element&gt;\r\n         &lt;\/xs:sequence&gt;\r\n      &lt;\/xs:complexType&gt;\r\n   &lt;\/xs:element&gt;\r\n\t\r\n    &lt;!-- ################################################### --&gt;\r\n    &lt;!-- ################# Type definitions ################ --&gt;\r\n    &lt;!-- ################################################### --&gt;\r\n\r\n\t&lt;!--  Enum type  --&gt;\r\n\t &lt;xs:simpleType name=&quot;Operation&quot;&gt;\r\n\t    &lt;xs:annotation&gt;&lt;xs:documentation&gt;Defines the arithmetic operations&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;\r\n\t\t&lt;xs:restriction base=&quot;xs:string&quot;&gt;\r\n\t\t\t&lt;xs:enumeration value=&quot;ADD&quot;&gt;&lt;xs:annotation&gt;&lt;xs:documentation&gt;Add&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;&lt;\/xs:enumeration&gt;\r\n\t\t\t&lt;xs:enumeration value=&quot;SUBTRACT&quot;&gt;&lt;xs:annotation&gt;&lt;xs:documentation&gt;Substract&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;&lt;\/xs:enumeration&gt;\r\n\t\t\t&lt;xs:enumeration value=&quot;MULTIPLY&quot;&gt;&lt;xs:annotation&gt;&lt;xs:documentation&gt;Multiply&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;&lt;\/xs:enumeration&gt;\r\n\t\t\t&lt;xs:enumeration value=&quot;DIVIDE&quot;&gt;&lt;xs:annotation&gt;&lt;xs:documentation&gt;Divide&lt;\/xs:documentation&gt;&lt;\/xs:annotation&gt;&lt;\/xs:enumeration&gt;\r\n\t\t&lt;\/xs:restriction&gt;\r\n\t&lt;\/xs:simpleType&gt;\r\n\r\n        &lt;xs:simpleType name=&quot;decimal9F2&quot;&gt;\r\n          &lt;xs:restriction base=&quot;xs:decimal&quot;&gt;\r\n            &lt;xs:totalDigits value=&quot;9&quot;\/&gt;\r\n            &lt;xs:fractionDigits value=&quot;2&quot;\/&gt;\r\n          &lt;\/xs:restriction&gt;\r\n        &lt;\/xs:simpleType&gt;\r\n\r\n&lt;\/xs:schema&gt;\r\n<\/pre>\n<p>The schema is part of an example project which can be downloaded <a href=\"http:\/\/www.pleus.net\/download\/SSD_Calculator_v1.zip\" target=\"_blank\">here<\/a>.<\/p>\n<p>A more appealing representation would look as follows:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/calculatorsimple3.png\" target=\"_blank\"><img decoding=\"async\" class=\"alignnone size-full wp-image-2560\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/calculatorsimple3.png\"\/><\/a><\/p>\n<p>In order to turn this schema into code we can call the xjb tool which is part of the Java SDK on the command line like this:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nxjc calculator.xsd\r\n<\/pre>\n<p>As a result we get Java code that we can incorporate in our code base. Another option is to generate the Java code from our Maven build. This can be achieved by adding following Maven Plugin to your pom.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n&lt;plugin&gt;\r\n\t&lt;groupId&gt;org.jvnet.jaxb2.maven2&lt;\/groupId&gt;\r\n\t&lt;artifactId&gt;maven-jaxb2-plugin&lt;\/artifactId&gt;\r\n\t&lt;version&gt;0.8.1&lt;\/version&gt;\r\n\t&lt;executions&gt;\r\n\t\t&lt;execution&gt;\r\n\t\t\t&lt;goals&gt;\r\n\t\t\t\t&lt;goal&gt;generate&lt;\/goal&gt;\r\n\t\t\t&lt;\/goals&gt;\r\n\t\t&lt;\/execution&gt;\r\n\t&lt;\/executions&gt;\r\n\t&lt;configuration&gt;\r\n\t\t&lt;schemaDirectory&gt;${project.basedir}\/src\/main\/resources\/xsd&lt;\/schemaDirectory&gt;\r\n\t\t&lt;bindingDirectory&gt;${project.basedir}\/src\/main\/resources\/xsd&lt;\/bindingDirectory&gt;  \r\n                &lt;generatePackage&gt;net.pleus.services.calculator.api.model&lt;\/generatePackage&gt;\r\n\t&lt;\/configuration&gt;\r\n&lt;\/plugin&gt;\r\n\r\n<\/pre>\n<p>As a result we get basic Java classes that represent the messages and types defined in our schema. If you want to affect the way the code is generated you can provide xjb binding files to customize the generated code. If you want for example use <em>java.util.Calendar<\/em> to be generated for an <em>xsd:date<\/em> type you can use the following binding:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n&lt;jaxb:bindings version=&quot;2.1&quot;\r\n    xmlns:jaxb=&quot;http:\/\/java.sun.com\/xml\/ns\/jaxb&quot;\r\n    xmlns:xjc=&quot;http:\/\/java.sun.com\/xml\/ns\/jaxb\/xjc&quot;\r\n    xmlns:xsd=&quot;http:\/\/www.w3.org\/2001\/XMLSchema&quot;&gt;\r\n    &lt;jaxb:globalBindings generateElementProperty=&quot;false&quot;&gt;\r\n      &lt;jaxb:javaType name=&quot;java.util.Calendar&quot; xmlType=&quot;xsd:date&quot;  \r\n             parseMethod=&quot;javax.xml.bind.DatatypeConverter.parseDate&quot;  \r\n             printMethod=&quot;javax.xml.bind.DatatypeConverter.printDate&quot;&gt;\r\n      &lt;\/jaxb:javaType&gt;  \r\n    &lt;\/jaxb:globalBindings&gt;   \r\n&lt;\/jaxb:bindings&gt; \r\n\r\n<\/pre>\n<p>Just drop the file jaxbbinding.xjb in the the same directory as your xsd file.<\/p>\n<p><strong>The foundation<\/strong><br \/>\nWe now have a simple Java class without any additional features:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/simple.png\" target=\"_blank\"><img decoding=\"async\" class=\"alignnone size-full wp-image-2560\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/simple.png\"\/><\/a><\/p>\n<p>JAXB comes with very useful plugins to pimp our generated code.<\/p>\n<p><strong>HashCode, equals, toString<\/strong><br \/>\nIf we want standard operations such as hashCode, equals or toString we can use the plugin <em>org.jvnet.jaxb2_commons:jaxb2-basics<\/em>.<\/p>\n<p>This gives us:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/basic2.png\" target=\"_blank\"><img decoding=\"async\" class=\"alignnone size-full wp-image-2560\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/basic2.png\"\/><\/a><\/p>\n<p><strong>Value Constructor<\/strong><br \/>\nIf we want value constructors, we can use the plugin <em>org.jvnet.jaxb2_commons:jaxb2-value-constructor<\/em>.<\/p>\n<p>The result is:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/value2.png\" target=\"_blank\"><img decoding=\"async\" class=\"alignnone size-full wp-image-2560\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/value2.png\"\/><\/a><\/p>\n<p><strong>Fluent APIs<\/strong><br \/>\nFluent APIs can be generated with the plugin <em>net.java.dev.jaxb2-commons:jaxb-fluent-api<\/em>.<\/p>\n<p>This gives us a very nice fluent API to produce intuitive and readable code.<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/fluent.png\" target=\"_blank\"><img decoding=\"async\" class=\"alignnone size-full wp-image-2560\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/fluent.png\"\/><\/a><\/p>\n<p><strong>Bean Validation<\/strong><br \/>\nOne great aspect of schema first design is that one can nicely define types and constraints like <em>tns:decimal9F2<\/em> shown in the listing at the top of this page. Wouldn&#8217;t it be nice if we could check those constraints in our code without additional effort? The plugin <em>com.github.krasa:krasa-jaxb-tools<\/em> generates JSR349 compliant bean validation annotations from our XSD types. After running the build we get annotated classes shown below for <em>valueA<\/em> which appears in the xsd as <em>tns:decimal9F2<\/em>:<\/p>\n<pre class=\"brush:java\">\r\n\r\n@NotNull\r\n@Digits(integer = 7, fraction = 2)\r\nprotected BigDecimal valueA;\r\n\r\n<\/pre>\n<p>To trigger the validation from your code we just need the following code snippet:<\/p>\n<pre class=\"brush:java\">\r\n\r\nimport javax.validation.*;\r\n\r\nValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();\r\nSet&lt;ConstraintViolation&lt;PerformSimpleCalculationRequest>> violations = validatorFactory.getValidator().validate(request);\r\nfor(ConstraintViolation&lt;PerformSimpleCalculationRequest> violation : violations){\r\n  System.out.println(\"Violation: \" + violation);\r\n}\r\n\r\n<\/pre>\n<p><strong>Javadoc<\/strong><br \/>\nAnd finally it would be nice to have the documentation from within the XSD file in the generated Java code as well.<br \/>\nThis can be achieved by the <em>org.dpytel.jaxb:xjc-javadoc<\/em> plugin.<\/p>\n<p><a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/javadoc.png\" target=\"_blank\"><img decoding=\"async\" class=\"alignnone size-full wp-image-2560\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2015\/02\/javadoc.png\"\/><\/a><\/p>\n<p>If you have additional needs to manipulate the generated code, you can implement your own JAXB plugin which can be hooked into the build process. This gives you maximum flexibility and full control of the code generation.<\/p>\n<p>The entire plugin configuration is shown here:<\/p>\n<pre class=\"brush:xml\">\r\n\r\n<plugin>\r\n\t<groupId>org.jvnet.jaxb2.maven2<\/groupId>\r\n\t<artifactId>maven-jaxb2-plugin<\/artifactId>\r\n\t<version>0.8.1<\/version>\r\n\t<executions>\r\n\t\t<execution>\r\n\t\t\t<goals>\r\n\t\t\t\t<goal>generate<\/goal>\r\n\t\t\t<\/goals>\r\n\t\t<\/execution>\r\n\t<\/executions>\r\n\t<configuration>\r\n\t\t<extension>true<\/extension>\r\n\t\t<generatePackage>>net.pleus.services.calculator.api.model<\/generatePackage>\r\n\t\t<args>\r\n\t\t\t<arg>-Xinheritance<\/arg>\r\n\t\t\t<arg>-XtoString<\/arg>\r\n\t\t\t<arg>-XhashCode<\/arg>\r\n\t\t\t<arg>-Xequals<\/arg>\r\n\t\t\t<arg>-Xvalue-constructor<\/arg>\r\n\t\t\t<arg>-Xfluent-api<\/arg>\r\n                        <arg>-XJsr303Annotations<\/arg>\r\n\t\t<\/args>\r\n\t\t<schemaDirectory>${project.basedir}\/src\/main\/resources\/xsd<\/schemaDirectory>\r\n\t\t<bindingDirectory>${project.basedir}\/src\/main\/resources\/xsd<\/bindingDirectory>\r\n\t\t<plugins>\r\n\t\t\t<plugin>\r\n\t\t\t\t<groupId>org.jvnet.jaxb2_commons<\/groupId>\r\n\t\t\t\t<artifactId>jaxb2-basics<\/artifactId>\r\n\t\t\t\t<version>${jaxb2-basics.version}<\/version>\r\n\t\t\t<\/plugin>\r\n\t\t\t<plugin>\r\n\t\t\t\t<groupId>org.jvnet.jaxb2_commons<\/groupId>\r\n\t\t\t\t<artifactId>jaxb2-value-constructor<\/artifactId>\r\n\t\t\t\t<version>${jaxb2-value-constructor.version}<\/version>\r\n\t\t\t<\/plugin>\r\n\t\t\t<plugin>\r\n\t\t\t\t<groupId>net.java.dev.jaxb2-commons<\/groupId>\r\n\t\t\t\t<artifactId>jaxb-fluent-api<\/artifactId>\r\n\t\t\t\t<version>${jaxb-fluent-api.version}<\/version>\r\n\t\t\t<\/plugin>\r\n\t\t\t<plugin>\r\n     \t\t\t\t<groupId>com.github.krasa<\/groupId>\r\n\t\t\t\t<artifactId>krasa-jaxb-tools<\/artifactId>\r\n\t\t\t\t<version>${krasa-jaxb-tools.version}<\/version>\r\n\t\t\t<\/plugin>\r\n                        <plugin>\r\n\t\t                <groupId>org.dpytel.jaxb<\/groupId>\r\n  \t\t                <artifactId>xjc-javadoc<\/artifactId>\r\n\t\t                <version>${xjc-javadoc-version}<\/version>\r\n\t\t        <\/plugin>\r\n\t\t<\/plugins>\r\n\t<\/configuration>\r\n<\/plugin>\r\n\r\n<\/pre>\n<p>In this post I&#8217;ve shown how to turn contracts into code on the Java platform easily. The contracts are 100% reusable, interoperable and cross platform, of instance on the .NET platform. Here you would use <em>svcuitl.exe<\/em> to turn the contract into code.<\/p>\n<p>In part two I&#8217;m going to show how to <a href=\"http:\/\/www.pleus.net\/blog\/?p=2595\" target=\"_blank\">turn contracts in into documentation<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Interfaces are one of the most important parts in software design. Designing software around properly defined interfaces has many benefits for instance in the areas of consistency, maintainability and reuse. A well written contract describes precisely how software artefacts (or services) interact with each other. Approaches such as Sustainable Service Design or the BiPRO standards &hellip; <a href=\"https:\/\/www.pleus.net\/blog\/?p=2584\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Turn contracts into code<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,3],"tags":[53,59,62,77,60,25,54],"class_list":["post-2584","post","type-post","status-publish","format-standard","hentry","category-bpm","category-soa","tag-bipro","tag-jaxb","tag-maven","tag-soa","tag-ssd","tag-xml","tag-xsd"],"_links":{"self":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2584"}],"version-history":[{"count":68,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2584\/revisions"}],"predecessor-version":[{"id":3139,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2584\/revisions\/3139"}],"wp:attachment":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}