September 27, 2015

RESTful software requirements specification (part 3 of 4)


Pages: 1 2 3 4

UI mock-ups: Designing the UI

Specification

With all the information available now from the business model and the activity diagrams, we can easily model the UI with a mockup design tool.

Here are example mockups for all the UIs of this web application. Each mockup is accompanied by a short information section.

1. /books
Main entity: A List<Book> of all Books in the system 
Label / Link / Button Text EN Target URL Parameters
book.list.title Books
[0] (dynamic; see mockup) 2. /books/:id
  • id: book.id

2. /books/:id
 Main entity: The Book with the id provided
Link / Button Text EN Target URL Parameters
book.show.title Book {0}
order Order 3. /users/:user.id/orders/new?bookId=:book.id
  • user.id: The currently logged in user.id
  • book.id: the book.id provided
back Back 2. /books

3. /users/:user.id/orders/new?bookId=:book.id
 Main entity: A new instance of Order with book = the Book with the id provided
Link / Button Text EN Target URL Parameters
purchase Purchase 4. /users/:user.id/orders?created=:order.id
  • user.id: The currently logged in user.id
  • order.id: the order.id of the newly created order
back Back 2. /books/:id
  • book.id: the book.id provided

4. /users/:user.id/orders?created=:order.id
 Main entity: A List<Order> of all Orders in the system for the User with the id provided
Link / Button Text EN Target URL Parameters
order.list.title Order for user {0}
order.created New order {0} created successfully.
delete Delete 5. /users/:user.id/orders
  • user.id: The user.id provided
X X 5. /users/:user.id/orders
  • user.id: The user.id provided

5. /users/:user.id/orders
 Same as UI mask 4.

As you can see, we make heavy use of the information from the domain model as well as of I18N.

Because the business model’s properties’ labels have already been defined, we don’t need to repeat this information on the UI mockups. Thus, a simple “label” is enough. However, additional labels as well as links / buttons need to be internationalized as well. This is done in the accompanying details table. Labels which contain variables follow a simple bracket syntax.

Having the labeling information defined once and once only diminishes ambiguity and makes it easier to apply changes later on. There is no more information duplication.

The additional tables also create the link between the masks and as such between the UI mockups and the activity diagram.

It’s important to have unique identifiers for the links / buttons. I have used a number ([0]) for the one link without a unique id.

Also note that there’s probably more UI design related information you should document. Most importantly, the overall UI design (including e.g. global navigation menus), the detailed default design for every input component (e.g. date pickers) and how error / information messages / input prompts are displayed. Having these things defined in a central place, rather than for each individual UI mask, greatly improves overall readability and matches the way DRY compliant software is built, namely based on reusable components. I haven’t defined these things explicitly here to keep the example brief.

Implementation

With the information from these mockups and tables, it’s easy to implement the actual UIs using AngularJS-enhanced HTML markup. For instance, here is the implementation for mask no. 4.
<body>
    <h1>{{ 'order.list.title' | translate:user }}</h1>
    <div ng-show="errors != null" class="alert alert-danger" role="alert">
        <ul>
            <li ng-repeat="error in errors">{{error}}</li>
        </ul>
    </div>
    <div ng-show="created != null"  class="alert alert-success" role="alert">
        <span data-translate="order.created" data-translate-value-id="{{created}}"></span>
        <a href="" ng-click="delete(created)" class="pull-right">{{ 'general.delete' | translate }}</a>
    </div>
    <ul>
        <li ng-repeat="entity in entities">
            {{entity.id}}. {{entity.book.title}} ({{entity.deliveryDate | date:'yyyy-MM-dd'}}) <
            a href="" ng-click="delete(entity.id)">X</a>
        </li>
    </ul>
</body>
Note that the overall design is not defined for each individual page, but rather in a global template.

In order to keep things unified, the main entity of each mask is always initialized as entities (in case of a List) or entity (otherwise).

This will eventually be rendered like so:
Note that the RESTful URL is build as defined in the routing config earlier on.

Go to the project’s GitHub repository to see the source code of the other HTML pages.

Finally, don’t forget to add any additional I18N message keys to the bundle, for instance:
'order.list.title': 'Orders for user {{name}}',
'order.created': 'New order {{id}} created successfully.',
Note how AngularJS’ I18N facility supports variable replacement.


Pages: 1 2 3 4