Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Background

We've already discussed how to to add hypermedia to a resource using  using the standard HAL HAL _links and  and _embedded reserved  reserved properties. These properties These properties will cover the majority of your hypermedia needs. However, in this same article we introduced the the AddFormAction service  service to address hypermedia address hypermedia requirements that go beyond the design intent of the the _links and  and _embedded properties properties.

To understand the the AddFormAction service service, it is important to understand the inspiration behind its design: HTML. As most developers will recognizewill recognize, HTML is both a media type and a  and a markup language. Because it is a media type, we can borrow from its well defined and understood understood hypermedia controls when  when defining similar capabilities for the JSON media type. In HTML, we find that that hypermedia controls are  are used for three general three general purposes:

  1. To To identify related resources through  through hyperlinks that allow the client to change the application state (e.g., the the <a> tag).
  2. To To embed resources from  from another URI into the current resource (e.g., the the <img> tag).
  3. To provide the client client input and submit capabilities to  to interact with the current resource (e.g., the the <form> tag.)

It would seem that HAL covers the first two purposes reasonably well. The The _links property  property provides the same purpose as the the <a> tag  tag and the the _em bedded property embedded property provides the same purpose as tags like like <img> (which is just one of a few tags that embed resources). However, the third purpose third purpose - the ability to provide richer interaction with the resource via form-like controls - is not addressed by HAL.

New Reserved Property: _forms

In keeping with the spirit of HTML hypermedia controls, the SRP HTTP Framework supports a custom property called called _forms. It serves the same purpose same purpose as the HTML HTML <form> tag  tag and borrows some of the same element names. Here is an example of what what _forms hypermedia  hypermedia controls looks likelooks like:

Code Block
languagediffjs
{  
   "_forms":{  
      "addPhone":{  
         "method":"POST",
         "action":"https://www.examples.org/api/user/matthew/phone",
         "title":"Add Phone",
         "fields":{  
            "type":{  
               "default":"Cell",
               "required":true,
               "visible":true
            },
            "number":{  
               "default":"",
               "required":true,
               "visible":true
            }
         }
      }
   }
}

The The _forms property  property contains one or more more sub-properties. Each Each sub-property name  name defines a unique unique form action and  and is typically named in a verba verb+noun format (e.g., addPhone in  in the above example). The The sub-property values  values are themselves additional sub-property name/value pairs.

Each defined defined form action contains  contains the following following sub-properties:

  • method to  to indicate the HTTP method used when making the request to the server. (Required)
  • action to  to indicate the target URI for the request. (Required)
  • title to  to provide a user-friendly label for the the form action. (Optional)
  • fields to  to identify relevant properties from the primary resource object and object and to document how they are to be handled. (Optional)

In the above example, the intent of this this form action is  is to describe how a new phone number can be added to the current resource. Clients should be should be able to consume this meta data and discover that this is done by sending a JSON object containing the the type and  and number properties  properties via a POST to the indicated URI.

fields Sub-Property

The The fields sub sub-property contains one or more more sub-properties. Each of these these sub-properties are the  are the names of a property in  in the primary resource objectresource object. In the above example, type and  and number are  are expected to be properties within the primary resource object. The The sub-property values are themselves  values are themselves additional sub-property name/value pairs.

Each defined defined field name contains  contains one or more of the following following sub-properties:

  • default to  to indicate the value of the resource object property that should be submitted unless overridden by the client.
  • required to  to indicate that this resource object property must have a value in order for the the form action to  to be accepted.
  • visible to  to indicate if this resource object property should be visible to the client.

Hierarchical Outline

To help visualize the _forms structure, here is a general outline:

Infopanel
iconfalse
  • _forms
    • form action 1form action 1
      • method
      • action
      • title
      • fields
        • field
         1
        • 1
          • default
          • required
          • visible
        • field
         2
        • 2
          • default
          • required
          • visible
      form action
    • form action 2
      • method
      • action
      • title
      • fields
        • field
         1
        • 1
          • default
          • required
          • visible
        • field
         2
        • 2
          • default
          • required
          • visible

Using the AddFormAction Service AddFormAction Service

With our background out of the way, we can now demonstrate how to call the the AddFormAction service service. To make this easy, we'll implement the the form action that  that appears in the above example:

Code Block
languagejs
API customers.ID.GET

    KeyID           = EndpointSegment
    
    ColumnNames     = 'FIRST_NAME' : @FM : 'LAST_NAME' : @FM : 'ADDRESS' : @FM : 'CITY' : @FM : 'STATE' : @FM : 'ZIP'
    PropertyNames   = 'firstName' : @FM : 'lastName' : @FM : 'address' : @FM : 'city' : @FM : 'state' : @FM : 'zipCode'
    // Create a JSON object in memory.
    objResource     = HTTP_Resource_Services('GetObject', 'CUSTOMERS', KeyID, ColumnNames, PropertyNames)
    
    If Error_Services('NoError') then
        // Add _forms sub-property hypermedia control.
        Fields          = 'type' : @FM : 'number'
        FieldProperties = 'Cell' : @VM : True$ : @VM : True$ : @FM : '' : @VM : True$ : @VM : True$
        HTTP_Resource_Services('AddFormAction', objResource, 'addPhone', 'POST', FullEndpointURL, 'Add Phone', Fields, FieldProperties)
    end
    
    If Error_Services('NoError') then
        // Serialize the JSON object.
        jsonResource    = HTTP_Resource_Services('GetSerializedResource', objResource)
        // Set the response body with the serialized JSON object and set the Content-Type response header.
        HTTP_Services('SetResponseBody', jsonResource, False$, 'application/hal+json')
    end else
        // There is an error condition so call the SetResponseError service.
        HTTP_Services('SetResponseError', '', '', 500, Error_Services ('GetMessage'), FullEndpointURL)
    end
    
end api