[[introduction]]
= Introduction

: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:


View models are similar to entities in that (unlike domain services) there can be many instances of any given type.
End users interact with view models in the same way as a domain entity, indeed they are unlikely to distinguish one from the other.

However, whereas domain entities are mapped to a datastore, view models are not.
Instead, they are recreated dynamically by serializing their state, ultimately into the URL itself (meaning their state it is in effect implicitly managed by the client browser).
You will notice that the URL for view models (as shown in xref:vw:ROOT:about.adoc[Web UI (Wicket viewer)] or xref:vro:ROOT:about.adoc[RestfulObjects viewer]) tends to be quite long.

This capability opens up a number of more advanced use cases:

* In the same way that an (RDBMS) database view can aggregate and abstract from multiple underlying database tables, a view model sits on top of one or many underlying entities.

* A view model could also be used as a proxy for some externally managed entity, accessed over a web service or REST API; it could even be a representation of state held in-memory (such as user preferences, for example).

* view models can also be used to support a particular use case.
An example that comes to mind is to expose a list of scanned PDFs to be processed as an "intray", showing the list of PDFs on one side of the page, and the current PDF being viewed on the other.
Such view models are part of the application layer, not part of the domain layer (where entities live).

We explore these use cases in more detail below.



== Application-layer view models

Domain entities (whether locally persisted or managed externally) are the bread-and-butter of Apache Causeway applications: the focus after all, should be on the business domain concepts and ensuring that they are solid.
Generally those domain entities will make sense to the business domain experts: they form the _ubiquitous language_ of the domain.
These domain entities are part of the domain layer.

When developing an Apache Causeway application you will most likely start off with the persistent domain entities: `Customer`, `Order`, `Product`, and so on.
For some applications this may well suffice.

That said, it may not always be practical to expect end-users of the application to interact solely with those domain entities.
If the application needs to integrate with other systems, or if the application needs to support reasonably complex business processes, then you may need to look beyond just domain entities; view models are the tool of choice.

One such use case for view models is to help co-ordinate complex business processes; for example to perform a quarterly invoicing run, or to upload annual interest rates from an Excel spreadsheet, or prepare payment batches from incoming invoices, to be uploaded to an external payment system.
In these cases the view model managing the business process might have some state of its own, but in most cases that state does not need to be persisted between user sessions.
Many of the actions will be queries but in some cases such view model actions might also modify state of underlying domain entities.
Either way, ultimately these actions just delegate down to the domain-layer.

.Desire Lines
****
One way to think of application view models is that they model the "desire line": the commonly-trod path that end-users must follow to get from point A to point B as quickly as possible.

To explain: there are link:http://ask.metafilter.com/62599/Where-the-sidewalk-ends[documented] link:https://sivers.org/walkways[examples] link:http://www.softpanorama.org/People/Wall/larry_wall_articles_and_interviews.shtml[that] architects of university campus will only add in paths some while after the campus buildings are complete: let the pedestrians figure out the routes they want to take.
One name for this idea is "desire lines".

What that means is you should add view models _after_ having built up the domain layer, rather than before.
These view models pave that commonly-trod path, automating the steps that the end-user would otherwise have to do by hand.

However, you _shouldn't_ try to build out a domain layer that could support every conceivable use case before starting to think about view models.
Instead, iterate.
Identify the use case/story/end-user objective that will deliver value to the business.
Build out the minimum domain entities to support that use case.
Then, introduce view models to simplify high-volume end-user interactions with the system (perhaps automating several related use cases together).
****

Another common requirement is to show a dashboard of the most significant data in the system to a user, often pulling in and aggregating information from multiple points of the app.
Obtaining this information by hand (by querying the respective services/repositories) would be tedious and slow; far better to have a dashboard do the job for the end user.

A dashboard object is a model of the most relevant state to the end-user, in other words it is (quite literally) a view model.
It is not a persisted entity, instead it belongs to the application layer.

== Self-persisting Domain entities

Sometimes we may have domain entities whose persistence is _not_ managed by JDO or JPA mechanism, in other words they take responsibility for their own persistence.
Because such entities are responsible for their own state management, they can be implemented as view models.


=== Externally-managed entities

Sometimes the entities that make up your application are persisted not in the local database but reside in some other system, for example accessible only through a SOAP web service.
Logically that data might still be considered a domain entity and we might want to associate behaviour with it, however it cannot be modelled as a domain entity if only because JDO/DataNucleus doesn't know about the entity nor how to retrieve or update it.

There are a couple of ways around this: we could either replicate the data somehow from the external system into the Causeway-managed database (in which case it is once again just another domain entity), or we could set up a stub/proxy for the externally managed entity.
This proxy would hold the reference to the externally-managed domain entity (eg an external id), as well as the "smarts" to know how to interact with that entity (by making SOAP web service calls etc).

The stub/proxy is a type of view model: a view -- if you like -- onto the domain entity managed by the external system.


=== Internal entities

Alternatively, perhaps your application has an entity that is best persisted not in a relational database but instead in a custom datastore, for example a graph database such as neo4j.

=== In-memory entities

As a variation on the above, sometimes there are domain objects that are, conceptually at least entities, but whose state is not actually persisted anywhere, merely held in-memory (eg in a hash).

A simple example is read-only configuration data that is read from a config file (eg log4j appender definitions) but thereafter is presented in the UI just like any other entity.

== DTOs

DTOs (data transfer objects) are simple classes that (according to link:https://en.wikipedia.org/wiki/Data_transfer_object[wikipedia]) "carry data between processes".

If those two processes are parts of the same overall application (the same team builds and deploys both server and client) then there's generally no need to define a DTO; just access the entities using Apache Causeway' xref:vro:ROOT:about.adoc[RestfulObjects viewer].

On the other hand, if the client consuming the DTO is a different application -- by which we mean developed/deployed by a different (possible third-party) team -- then the DTOs act as a formal contract between the provider and the consumer.
In such cases, exposing domain entities over xref:vro:ROOT:about.adoc[RestfulObjects] would be "A Bad Thing"(TM) because the consumer would in effect have access to implementation details that could then not be easily changed by the producer.
There's plenty of discussion on this topic (eg link:https://stackoverflow.com/questions/36174516/rest-api-dtos-or-not[here] and link:https://juristr.com/blog/2012/10/lessions-learned-dont-expose-ef-entities-to-the-client-directly/[here]).
Almost all of these recommend exposing only DTOs (which is to say view models), not domain entities, in REST APIs.

To support this use case, a view model can be defined such that it can act as a DTO.
This is done by annotating the class using JAXB annotations; this allows the consumer to obtain the DTO in XML format along with a corresponding XSD schema describing the structure of that XML.


These DTOs are still usable as "regular" view models; they will render in the xref:vw:ROOT:about.adoc[Web UI (Wicket viewer)] just like any other.
In fact (as the xref:userguide:ROOT:view-models.adoc#jaxb[programming model] section below makes clear), these JAXB-annotated view models are in many regards the most powerful of all the alternative ways of writing view models.

It's also worth noting that it is also possible to download the XML (or XSD) straight from the UI, useful during development.
The view model simply needs to implement the xref:refguide:applib:index/mixins/dto/Dto.adoc[Dto] marker interface; the framework has xref:refguide:applib-classes:mixees-and-mixins.adoc#Dto[mixins] that contribute the download actions to the view model.

== For REST Clients

The xref:vro:ROOT:about.adoc[Restful Objects] viewer automatically provides a REST API for both domain entities.
Or, you can use it to only expose view models, taking care to map the state of the domain entity/ies into a view model.
The question to consider is whether the REST API is a public API or an internal private API:

* If it's a public API, which is to say that there are third-party clients out over which you have no control, then view models are the way to go.
+
In this case view models provide an isolation layer which allow you to modify the structure of the underlying domain entities without breaking this API.

* If it's a private API, which is to say that the only clients of the REST API are under your control, then view models are an unnecessary overhead.
+
In this case, just expose domain entities directly.

The caveat to the "private API" option is that private APIs have a habit of becoming public APIs.
Even if the REST API is only exposed within your organisation's intranet, other teams may "discover" your REST API and start writing applications that consume it.
If that REST API is exposing domain entities, you could easily break those other teams' clients if you refactor.

[NOTE]
====
The link:https://projects.spring.io/spring-data-rest/[Spring Data REST] subproject has a similar capability of being able to expose domain entities as REST resources.
This link:https://stackoverflow.com/questions/38874746/is-it-problematic-that-spring-data-rest-exposes-entities-via-rest-resources-with[SO question], which debates the pros-and-cons, is also worth a read.
====

If your REST API is intended to be public (or you can't be sure that it will remain private), then exposing view models will entail a lot of marshalling of state from domain entities into view models.
There are numerous open source tools that can help with that, for example link:http://modelmapper.org/[Model Mapper], link:http://dozer.sourceforge.net/[Dozer] and link:https://github.com/orika-mapper/orika[Orika].

Or, rather than marshalling state, the view model could hold a reference to the underlying domain entity/ies and dynamically read from it (ie, all the view model's properties are derived from the entity's).

A third option is to define an RDBMS view, and then map a "non-durable" entity to that view.
The RDBMS view then becomes the public API that must be preserved.
ORMs such as DataNucleus link:http://www.datanucleus.org:15080/products/accessplatform_5_1/jdo/mapping.html#schema_rdbms_views[support this].


