:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
:page-partial:



== Example

The examples in this section uses the DTO for a `ToDoItem` entity.
The DTO is defined as follows:

[source,java]
----
package todoapp.app.viewmodels.todoitem.v1;                         // <.>
@XmlRootElement(name = "toDoItemDto")                               // <.>
@XmlType(
        propOrder = {                                               // <.>
            "majorVersion", "minorVersion",
            "description", "category", ...
            "toDoItem", "similarItems"
        }
)
@DomainObjectLayout(
        titleUiEvent = TitleUiEvent.Doop.class                      // <.>
)
public class ToDoItemV1_1 implements Dto {                          // <.>

    @XmlElement(required = true, defaultValue = "1")                // <.>
    public final String getMajorVersion() { return "1"; }
    @XmlElement(required = true, defaultValue = "1")                // <.>
    public String getMinorVersion() { return "1"; }

    @XmlElement(required = true)                                    // <.>
    @Getter @Setter
    protected String description;
    @XmlElement(required = true)
    @Getter @Setter
    protected String category;
    ...

    @Getter @Setter                                                 // <.>
    protected ToDoItem toDoItem;
    @XmlElementWrapper                                              // <.>
    @XmlElement(name = "todoItem")
    @Getter @Setter
    protected List<ToDoItem> similarItems = Lists.newArrayList();
}
----
<.> package name encodes major version, so it can be serialized; see discussion on xref:#versioning[versioning below]
<.> identifies this class as a view model and defines the root element for JAXB serialization
<.> all properties in the class must be listed; (they can be ignored using `@XmlTransient`)
<.> demonstrating use of UI events for a subscriber to provide the DTO's title; see xref:refguide:applib:index/annotation/DomainObjectLayout.adoc#titleUiEvent[@DomainObjectLayout#titleUiEvent()].
<.> class name encodes (major and) minor version; see discussion on xref:#versioning[versioning]
<.> again, see discussion on xref:#versioning[versioning]
<.> again, see discussion on xref:#versioning[versioning]
<.> simple scalar properties
<.> reference to a persistent entity; discussed xref:userguide:fun:view-models.adoc#referencing-domain-entities[here]
<.> reference to a collection of persistent entities; again discussed xref:userguide:fun:view-models.adoc#referencing-domain-entities[here]




[#versioning]
=== Versioning

The whole point of using DTOs (in Apache Isis, at least) is to define a formal contact between two inter-operating but independent applications.
Since the only thing we can predict about the future with any certainty is that one or both of these applications will change, we should version DTOs from the get-go.
This allows us to make changes going forward without unnecessarily breaking existing consumers of the data.

[NOTE]
====
There are several ways that versioning might be accomplished; we base our guidelines on this link:http://www.xfront.com/Versioning.pdf[article] taken from Roger Costello's blog, well worth a read.
====

We can distinguish two types of changes:

* backwardly compatible changes
* breaking changes.

The XSD namespace should change only when there is a major/breaking change.
If following link:http://semver.org[semantic versioning] that means when we bump the major version number v1, v2, etc.

XML namespaces correspond (when using JAXB) to Java packages.
We should therefore place our DTOs in a package that contains only the major number; this package will eventually contain a range of DTOs that are intended to be backwardly compatible with one another.
The package should also have a `package-info.java`; it is this that declares the XSD namespace:

[source,java]
----
@javax.xml.bind.annotation.XmlSchema(
    namespace = "http://viewmodels.app.todoapp/todoitem/v1/Dto.xsd",    // <.>
    xmlns = {
        @javax.xml.bind.annotation.XmlNs(
            namespaceURI = "http://isis.apache.org/schema/common",
            prefix = "com"
        )
    },
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
)
package todoapp.app.viewmodels.todoitem.v1;                             // <.>
----
<.> the namespace URI, used by the DTO residing in this package.
<.> the package in which the DTO resides.  Note that this contains only the major version.

Although there is no requirement for the namespace URI to correspond to a physical URL, it should be unique.
This usually means including a company domain name within the string.

As noted above, this package will contain multiple DTO classes all with the same namespace; these represent a set of minor versions of the DTO, each subsequent one intended to be backwardly compatible with the previous.
Since these DTO classes will all be in the same package (as per the advice above), the class should therefore include the minor version name:

[source,java]
----
package todoapp.app.viewmodels.todoitem.v1;     // <.>
...
public class ToDoItemV1_1 implements Dto {      // <.>
    ...
}
----
<.> package contains the major version only
<.> DTO class contains the (major and) minor version


We also recommend that each DTO instance should also specify the version of the XSD schema that it is logically compatible with.
Probably most consumers will not persist the DTOs; they will be processed and then discarded.
However, it would be wrong to assume that is the case in all cases; some consumers might choose to persist the DTO (eg for replay at some later state).

Thus:

[source,java]
----
public class ToDoItemV1_1 implements Dto {
    @XmlElement(required = true, defaultValue = "1")
    public final String getMajorVersion() { return "1"; }   // <.>
    @XmlElement(required = true, defaultValue = "1")
    public String getMinorVersion() { return "1"; }         // <.>
    ...
}
----
<.> returns the major version (in sync with the package)
<.> returns the minor version (in sync with the class name)

These methods always return a hard-coded literal.
Any instances serialized from these classes will implicitly "declare" the (major and) minor version of the schema with which they are compatible.
If a consumer has a minimum version that it requires, it can therefore inspect the XML instance itself to determine if it is able to consume said XML.

If a new (minor) version of a DTO is required, then we recommend copying-and-pasting the previous version, eg:

[source,java]
----
public class ToDoItemV1_2 implements Dto {
    @XmlElement(required = true, defaultValue = "1")
    public final String getMajorVersion() { return "1"; }
    @XmlElement(required = true, defaultValue = "2")
    public String getMinorVersion() { return "2"; }
    ...
}
----

Obviously, only changes made must be backward compatible, eg new members must be optional.

Alternatively, you might also consider simply editing the source file, ie renaming the class and bumping up the value returned by `getMinorVersion()`.






=== DTO Consumers

The actual consumers of DTOs will generally obtain the XML of the view models either by requesting the XML directly, eg using the xref:vro:ROOT:about.adoc[RestfulObjects viewer], or may have the XML sent to them asynchronously using an ESB such as Apache Camel.

In the former case, the consumer requests the DTO by calling the REST API with the appropriate HTTP `Accept` header.
An appropriate implementation of xref:refguide:applib:index/services/conmap/ContentMappingService.adoc[ContentMappingService] can then be used to return the appropriate DTO (as XML).

For the latter case, one design is simply for the application to instantiate the view model, then call the xref:refguide:applib:index/services/jaxb/JaxbService.adoc[JaxbService] to obtain its corresponding XML.  This can then be published onto the ESB, for example using an http://activemq.apache.org[Apache ActiveMQ (TM)] queue.

However, rather than try to push all the data that might be needed by any of these external systems in a single XML event (which would require anticipating all the requirements, likely a hopeless task), a better design is to publish only the fact that something of note has changed - ie, that an action on a domain object has been invoked - and then let the consumers call back to obtain other information if required.
This can once again be done by calling the REST API with an appropriate HTTP `Accept` header.

[TIP]
====
This is an example of the link:https://leanpub.com/camel-design-patterns[VETRO pattern] (validate, enrich, transform, route, operate).
In our case we focus on the validation (to determine the nature of the inbound message, ie which action was invoked), and the enrich (callback to obtain a DTO with additional information required by the consumer).
====

//The (non-ASF) link:https://platform.incode.org[Incode Platform^]'s publishmq module provides an out-of-the-box solution of this design.
//It provides an implementation of the xref:refguide:applib:index/services/publishing/spi/ExecutionSubscriber.adoc[ExecutionSubscriber], but which simply publishes instances of xref:refguide:schema:ixn.adoc[InteractionDto] to an ActiveMQ queue.
//Camel (or similar) can then be hooked up to consume these events from this queue, and use a processor to parse the action memento to determine what has changed on the source system.
//Thereafter, a subsequent Camel processor can then call back to the source - via the xref:vro:ROOT:about.adoc[REST API (Restful Objects viewer)] - to enrich the message with additional details using a DTO.



== See also

* xref:refguide:applib:index/mixins/dto/Dto_downloadXml.adoc[Dto_downloadXml]
* xref:refguide:applib:index/mixins/dto/Dto_downloadXsd.adoc[Dto_downloadXsd]

