= Layout Resources

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


Apache Isis' Restful Objects viewer provides a number of additional resource endpoints (not defined in the xref:ro-spec.adoc[RO spec]) that provide representations of the object layout (as per xref:refguide:applib:index/services/grid/GridService.adoc[GridService]) and of the menu layout (as per xref:refguide:applib:index/services/menu/MenuBarsService.adoc[MenuBarsService]).

This chapter provides details of these resources, the link ``Rel``s to access them, and the resultant representations.

[#menubars]
== MenuBars

The xref:refguide:applib:index/services/menu/MenuBarsService.adoc[MenuBarsService] provides the `menu.layout.xml` XML document which defines how to group the various domain service actions into menubars, menus and menu sections.

For example, the xref:docs:starters:helloworld.adoc[Hello World starter app] has the following layout:

[source,xml]
----
<mb3:menuBars
    xsi:schemaLocation="..."
    xmlns:cpt="http://isis.apache.org/applib/layout/component"
    xmlns:lnk="http://isis.apache.org/applib/layout/links"
    xmlns:mb3="http://isis.apache.org/applib/layout/menubars/bootstrap3"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <mb3:primary>
        <mb3:menu>
            <mb3:named>Hello World Objects</mb3:named>
            <mb3:section>
                <mb3:serviceAction objectType="helloworld.HelloWorldObjects" id="create">
                    <cpt:named>Create</cpt:named>
                </mb3:serviceAction>
                ...
            </mb3:section>
        </mb3:menu>
        <mb3:menu unreferencedActions="true">
            <mb3:named>Other</mb3:named>
        </mb3:menu>
        ...
    </mb3:primary>
    <mb3:secondary>
        ...
    </mb3:secondary>
    <mb3:tertiary>
        ...
    </mb3:tertiary>
</mb3:menuBars>
----

Note that exactly one `<mb3:menu>` must have the `unreferencedActions` flag set.
Any service actions that are not explicitly listed will be added to this menu.

The representation returned by home page resource (link:https://www.restfulobjects.org/spec/1.0/section-b/chapter-05.html#5.2-representation[section 5.2 of the RO spec v1.0]) has been extended to provide a link to this resource:

[source,javascript]
----
{
  "links": [
    ...
    {
      "rel": "urn:org.apache.isis.restfulobjects:rels/menuBars",
      "href": "http://localhost:8080/restful/menuBars",
      "method": "GET",
      "type": "application/json;profile='urn:org.restfulobjects:repr-types/layout-menubars'"
    },
  ],
  ...
}
----

The representation returned by the `/menuBars` resource (assuming an HTTP header of `Accept: application/xml`) is a superset of the `menu.layout.xml`; each action also includes a `link` to the corresponding Restful Objects resource:

[source,xml]
----
<mb3:serviceAction objectType="helloworld.HelloWorldObjects" id="create">
  <cpt:named>Create</cpt:named>
    <cpt:link>
      <lnk:rel>urn:org.restfulobjects:rels/action</lnk:rel>
        <lnk:method>GET</lnk:method>
        <lnk:href>
          http://localhost:8080/restful/objects/helloworld.HelloWorldObjects/1/actions/create
        </lnk:href>
        <lnk:type>
          application/json;profile="urn:org.restfulobjects:repr-types/object-action"
        </lnk:type>
  </cpt:link>
</mb3:serviceAction>
----

This can also be obtained in JSON format in the usual way (by specifying an HTTP header of `Accept: application/json`):

[source,json]
----
"serviceAction": [
{
  "objectType": "helloworld.HelloWorldObjects",
  "id": "create",
  "named": "Create",
  "link": {
    "rel": "urn:org.restfulobjects:rels/action",
    "method": "GET",
    "href": "http://localhost:8080/restful/objects/helloworld.HelloWorldObjects/1/actions/create",
    "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
  }
}
----

== Domain Object Icon

The representation returned by the domain object resource (link:https://www.restfulobjects.org/spec/1.0/section-c/chapter-14.html#14.4-representation[section 14.4] of the RO spec v1.0) has been extended to provide a link to the icon image (`.png`) to use:

[source,javascript]
----
{
  "links": [
    ...
    {
      "rel": "urn:org.apache.isis.restfulobjects:rels/object-layout",
      "href": "http://localhost:8080/restful/objects/helloworld.HelloWorldObject/0/object-icon",
      "method": "GET",
      "type": "image/png",
    },
  ],
  ...
}
----

Note that because of dynamic icons (the
xref:refguide:applib-methods:ui-hints.adoc#iconName[iconName()] supporting method) the image returned can vary on an instance-by-instance basis.

[#domain-object-layout]
== Domain Object Layout

The xref:refguide:applib:index/services/grid/GridService.adoc[GridService] provides an XML document which defines the layout of any of domain object.
Typically this is the contents of the `Xxx.layout.xml` file (where `Xxx` is the domain type).

For example, in the xref:docs:starters:helloworld.adoc[Hello World starter app] the `HelloWorld` domain object has a layout defined by `HelloWorld.layout.xml`.

The representation returned by the domain object resource (link:https://www.restfulobjects.org/spec/1.0/section-c/chapter-14.html#14.4-representation[section 14.4] of the RO spec v1.0) has been extended to provide a link to this resource:

[source,javascript]
----
{
  "links": [
    ...
    {
      "rel": "urn:org.apache.isis.restfulobjects:rels/object-layout",
      "href": "http://localhost:8080/restful/objects/helloworld.HelloWorldObject/0/object-layout",
      "method": "GET",
      "type": "application/json;profile='urn:org.restfulobjects:repr-types/object-layout-bs3'",
    },
  ],
  ...
}
----

In a similar way to the `menu.layout.xml`, the representations is supplemented with ``link``s nodes that link back to the standard Restful Objects resources:

* `domainObject`
* `property`
* `collection`
* `action`

For example, the layout for a "HelloWorldObject" instance in the hello world starter app (with `Accept: appication/xml` HTTP header) is:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- 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. -->
<bs3:grid xmlns:cpt="http://isis.apache.org/applib/layout/component"
          xmlns:lnk="http://isis.apache.org/applib/layout/links"
          xmlns:bs3="http://isis.apache.org/applib/layout/grid/bootstrap3">
  <bs3:row>
    <bs3:col span="12" unreferencedActions="true">
      <cpt:domainObject bookmarking="AS_ROOT">
          <cpt:link>
          <lnk:rel>urn:org.restfulobjects:rels/element</lnk:rel>
          <lnk:method>GET</lnk:method>
          <lnk:href>http://localhost:8080/restful/objects/helloworld.HelloWorldObject/0</lnk:href>
          <lnk:type>application/json;profile="urn:org.restfulobjects:repr-types/object"</lnk:type>
        </cpt:link>
      </cpt:domainObject>
    </bs3:col>
  </bs3:row>
  ...
</bs3:grid>
----

This can also be obtained as JSON (using `Accept: application/json` HTTP header):

[source,javascript]
----
{
  "row": [
    {
      "cols": [
        {
          "col": {
            "domainObject": {
              "link": {
                "rel": "urn:org.restfulobjects:rels/element",
                "method": "GET",
                "href": "http://localhost:8080/restful/objects/helloworld.HelloWorldObject/0",
                "type": "application/json;profile='urn:org.restfulobjects:repr-types/object'"
              },
              "bookmarking": "AS_ROOT",
            },
            "span": 12,
            "unreferencedActions": true
          }
        }
      ]
    }
    ...
  ]
}
----

== Domain Type Layout

The representation of the domain types resource (link:https://www.restfulobjects.org/spec/1.0/section-d/chapter-22.html#22.2-representation[section 22.2] of RO spec v1.0) has also been extended to return the (type) layout:

[source,javascript]
----
{
  "links": [
    ...
    {
      "rel": "urn:org.apache.isis.restfulobjects:rels/layout",
      "href": "http://localhost:8080/restful/domain-types/helloworld.HelloWorldObject/layout",
      "method": "GET",
      "type": "application/json;profile='urn:org.restfulobjects:repr-types/layout-bs3'"
    }
  ],
  ...
}
----

The representation returned by this resource is essentially exactly the same as the layout returned by xref:refguide:applib:index/services/grid/GridService.adoc[GridService] (it is not dynamically extended with links).

== Static vs Dynamic Resources

The xref:vro:ROOT:layout-resources.adoc#menubars[menu layout] representation includes all possible domain services; it does not follow that the current user has access to all of these actions (some may be hidden or disabled).

Similarly, the xref:vro:ROOT:layout-resources.adoc#domain-object-layout[domain object layout] representation include all _possible_ properties, collections and actions of the domain object; again, the current user may not have access to all of these members.
It is also often the case that the domain object's internal state will determine which members to make available (eg, show only one of "lock" and "unlock" actions at any given time).

To determine what should actually be rendered, the REST client should follow the links to the standard Restful Objects resources.
