DPS907 notes – week 6 – Oct 12 and Oct 15

Designing a media type formatter for a hypermedia representation. Documentation for your web service topics.

 

Agenda for the Friday class

Here’s the agenda for the Friday class:

  • Test 2
  • Code-based and out-of-band documentation
  • Web API Help Page feature
  • Mixing web app and web service controllers

 

Test today

Test 2 is today, at the beginning of the timeslot.

As discussed in class a few times, it will cover the week 5 content and the week 6 content.

Review the relevant info about tests on the week 2 notes page and on the graded work page.

The test will begin at the start of the class timeslot, at 3:20pm, and its duration will be about 40 minutes. It is worth 12%, which means that you will answer any questions that total 12 marks. Most questions are worth one mark, and a few are worth more.

After the test, we will cover the highlights of the week’s new topics.

 

Code examples

In the GitHub code example repository for this week, you will see several interesting assets.

HRFormatterICT

DocumentationIntro

WebAppAndService

 

Design a media type formatter for a hypermedia representation

This week, we will design a solution that will automatically generate a hypermedia representation (hr).

Last week, you learned how to manually generate an hr. You saw that the work was tedious, and it bloated the size of the code in the controller, which is something that we really do not want to do. There must be a better way.

In the past, you have learned something about the message-handling (or request-handling) pipeline. In ASP.NET web apps and services, the pipeline is configurable, with a number of locations that can accommodate plug-in custom code. We did this with the error handler, the OPTIONS method handler, and the media formatter for byte-oriented content.

For our solution, we will attempt to design a media formatter that will do the task. Why a media formatter? Well, it is a convenient way to deliver a response that’s customized. It’s easy to configure, and easy to use.

The implication of using a media formatter is that the requestor must include an “accept” header in the request, with a value that matches a custom and unique name for the internet media type that we will design.

 

Solution roadmap

This week, there are several tasks that we must do to write the media formatter.

First, we must study the typical use cases, and identify their typical request-response formats.

Then, we will anticipate the link relations that each use case will need.

From this, we will be able to discover or identify a number of patterns.

 

Request and response metadata (and data)

We will work through some scenarios in class. Then, right after, we may publish notes and code example(s).

Let’s identify the range of use cases. Then, we will look at each request and its response. We have a couple of goals:

  1. Identify the metadata that is typically present in the request
  2. Anticipate the links and actions that will be needed in the response

When we have done that, we will have a “recipe” for coding the media formatter.

The use cases:

  1. Get all
  2. Get some filtered
  3. Get one by id
  4. Get one, by some other value
  5. Get, using attribute-defined route
  6. Add new
  7. Edit existing (seldom done, instead, do a command)
  8. Delete item (seldom done)
  9. Command

Let’s deal with the easy ones first…

 

Delete item

Return type is void, which yields HTTP 204, no message body, and therefore no hr is needed.

Wait a minute… maybe this isn’t such a good idea…

In this article, Mark Seemann argues that we should avoid 204 responses.

Your professor tends to agree. However, we will avoid implementing his recommendation in our current discussions about hypermedia representation design. We may return to this a bit later in the course.

 

Command

Return type is void, which yields HTTP 204, no message body, and therefore no hr is needed.

Ditto above.

 

Others

Now, we can look at the others. What links must be created? How “deep” should we go? For our “version 1”:

  • In the item in the “data” property, there will usually (almost always? always?) have only one link
  • If the item (in the “data” property) includes associated data, that associated data does NOT get links

Methods… should we assume GET unless otherwise told? Yes, probably. Or explicitly send that all the time?

Same thing with (internet media) type? Assume JSON (or a custom variant)? Yes.

Can we discover or identify some common patterns? Yes. Continue below…

 

Get all

Pattern 1 – what data and metadata is available?:

  • 1 URI segment (after /api/, e.g. /api/customers)
  • 0+ items in the response

 

Get some filtered

Pattern 2:

  • 1 URI segment
  • 0+ items in the response
  • Request.GetQueryNameValuePairs() is not null

 

Get one by id

Pattern 3:

  • 2 URI segments (after /api/, e.g. /api/customers/123)
  • 1 item in the response
  • has id value (greater than zero)

 

Get one, by some other value

Pattern 4:

  • 2 URI segments
  • 1 item in the response
  • does NOT have id value (it will have some other value)

 

Get, using attribute-defined route

Pattern 5:

  • 3+ URI segments
  • 1 item in the response
  • has id value

 

Add new

Use pattern 3.

 

Edit existing (seldom done, instead, do a command)

Use pattern 3.

 

Links and actions (link relations) needed

Based on the work above, we may use a spreadsheet/workbook to begin designing the link relations for each use case, in a professor-led discussion.

We will rely on a modified version of the “link” and “MediaTypeExample” classes that we introduced last week.

 

Study the media formatter class

Study the HRFormatter.cs source code file that’s in this week’s code repository. It gets us started on the code we need for our hr solution.

The media formatter class is not yet complete. Part of the work done in the next programming assignment will add some missing functionality.

 

 

(end of Friday content, Monday content is below)

 

 

Agenda for the Monday class

Here’s the agenda for the Monday class:

  • Documentation for your web service
  • Mixing web app and web service controllers
  • Work on the assignment

 

Documentation for your web service

As you would expect, there are different kinds of documentation in a web service:

  1. Code comments
  2. Out-of-band (web page) documentation for users/requestors
  3. Embedded documentation in responses (hypermedia representations)

 

Code comments are for the programmer (duh). You should add code comments to introduce a section of code that needs it, and to explain logic that is not apparent or is dependent on context or disjointed knowledge.

Note, and reminder: You can – and should, as a new learner – use code comments as a way to create a coding plan or algorithm for a piece of logic. Very useful. Think about the problem, and write out code comments as you work through the step-by-step in your head or while talking to others. Then, it becomes easier to write code, because the coding plan is right in front of you.

 

Out-of-band documentation is for users/requestors. It is typically presented on a set of web pages. The ASP.NET Web API project type has a very nice documentation generator. If you do your part (explained below), it will automatically generate these web pages. Sweet.

Embedded documentation is found in the responses delivered to users/requestors. Recently, you learned about hypermedia representations, which implements this idea.

In the sections below, you will learn about out-of-band documentation.

 

Code comments, and
Out-of-band (web page) documentation

When you run your app, it loads in a browser. You may have noticed an “API” link on the top-of-page menu strip.

docs-built-in

 

The link will show you pages that are generated by the Web API Help Page feature. This feature is turned on in every new Web API project in Visual Studio 2015. (Its principal author is Yao Huang Lin.)

Its default configuration will show a list of all the requests that can be handled by your app’s controllers. It does this by looking for classes that inherit from ApiController, and then inspecting their methods and routes. The ApiExplorer class enables this feature.

In its default configuration, every documented request has a “Description” field that reads “No documentation available”. We should change that, to make the documentation more useful:

docs-built-in-configured

 

Implementing the Web API Help Page

There are several discrete tasks that need to be done to fully implement a useful Web API Help Page.

Change the project’s properties

Open the project properties panel, and show the Build settings.

In the “Errors and warnings” settings, add “CS1591” to the “Suppress warnings” textbox. As it suggests, it will suppress warnings for C# compiler warning number 1591.

In the “Output” settings, check (mark) the “XML documentation file” setting, and add a file path name (App_Data\XmlDocument.xml) to the textbox. As it suggests, the compiler will output/save the data to that named file.

Save, and close the project properties panel.

docs-properties-build

 

Configure the help page to use the just-configured XML documentation file

Open the source code file that holds the HelpPageConfig class. It’s in Areas > HelpPage > App_Start.

Uncomment the statement that sets/configures the XML documentation file:

docs-config-class

 

Add documentation to controller methods

For each public web service controller method, add XML Documentation Comments.

If you have never used this feature, here’s how to get started: Position the cursor on the line above the method declaration statement. Type a triple slash ( / / / ). That will add the structure. Then, fill it in with useful comments.

Incidentally, you can add XML Documentation Comments to every method and property, in every class, in your project. Then, during coding, Visual Studio will use the data as you write code, and show it with its code sense feature. (Yes, this is how Microsoft has done this for framework-provided code.)

docs-xml-comments

 

Where appropriate, identify the response type class

Most of our responses use the IHttpActionResult type. Great for us, but not enough for the Web API Help Page feature to figure out whether we are returning a “customer” or a “collection of products”.

We can solve this by adding an annotation to each controller method. As shown in the following code snippet, add the ResponseType annotation. It is in the System.Web.Http.Description namespace, so it must be named in the top-of-file list of “using” directives.

// GET: api/Customers/5
/// <summary>
/// Specific customer, using its identifier
/// </summary>
/// <param name="id">Customer identifier</param>
/// <returns>Customer object</returns>
[ResponseType(typeof(CustomerBase))]
public IHttpActionResult Get(int? id)
{
    // etc.

 

Recommendation – document resource model classes with an annotation

We noted above that you can add XML Documentation Comments to every method and property, in every class, in your project.

For resource model classes, we ALSO recommend that you add “Description” annotations. Doing this will enable reflection to work, and the upcoming code-generated hypermedia representation produce better results. The “Description” annotation is in another namespace, so you will be prompted to add it to the source code file’s “using” statements. Here’s an example:

/// <summary>
/// First (given) name of customer
/// </summary>
[Description("First (given) name of customer")]
public string FirstName { get; set; }
// etc.

 

When you build and run your project, the compiler will generate the content it needs to fully configure the Web API Help Page feature.

Please follow the instructions above. They are intended for late 2015 projects. However, you should also read/skim the original documents that describe the Web API Help Page feature, because they include some background information and so on. Be careful, because some of the documents are two or three years old, and may not (or will not) apply to current new projects.

Creating Help Pages for ASP.NET Web API, by Mike Wasson, April 2013

Introducing the ASP.NET Web API Help Page, by Yao Huang Lin, August 2012

More info, Part 1, Part 2, and Part 3, by Yao, also from 2012

 

Mixing web app (MVC) and web service (Web API) controllers
in the same project

Can you have web app (MVC) and web service (Web API) controllers in the same project? Yes.

What about resource URIs – can we have this, for the Employee entity, for example:

  • Web app – /employees, or /employees/detail/5
  • Web service – /api/employees, or /api/employees/5

Yes.

It requires a bit of extra work, however.

 

What could go wrong

Assume that you have an existing Web API controller for the Employee entity. Its source code file will be named EmployeesController, and the class inside the file will also be named EmployeesController. This you know.

Now, assume that you want to add a web app (MVC) controller. If you attempt to add another controller with the same name, it will not be possible. Your first reaction may be to choose a new name, but that will affect the resource URIs for the web app. If you choose an ugly name (e.g. Employees2Controller, or EmployeesMVCController), then it’s bad news.

 

How to solve 

We suggest that you make small modifications to the web service (Web API) controller. Doing this will clear the way for you to add a web app (MVC) controller. Here’s the suggested sequence, using the Employee entity as an example.

1. Create a Web API controller, named EmployeesController.

2. In Solution Explorer, rename the new source code file to EmployeesApiController. When asked “Would you also like to perform a rename…?”, answer No.

3. Change the namespace name to <projectname>.Controllers.Api.

4. Then, you can create an MVC controller, also named EmployeesController.

 

This all works because we are placing the Web API controller in a different namespace. That enables us to support two classes named EmployeesController, because they will be in different namespaces.

Note: It is not necessary to do this for every Web API controller. Do it when needed, whenever you want to support both an MVC controller and a Web API controller for the same entity/collection.

 

Work on the assignment

Work on the next assignment.

 

 

 

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Advertisements
%d bloggers like this: