HOPE Semantic Rendering of Microservice Data on the Browser

In a previous blog post, I described the high level architecture of microservices
running in a Docker container.  This blog post describes (again at a high level) the behind-the-scenes implementation of how a we render the output of a microservice back to the client’s browser. We’ll use the Weather Underground API for acquiring our current weather conditions.

First, let’s start with a semantic address:

public class ST_Address : ISemanticType
{
  public string Address1 { get; set; }
  public string Address2 { get; set; }
  public ST_City City { get; set; }
  public ST_State State { get; set; }
  public ST_Zip Zip { get; set; }

  public ST_Address()
  {
    City = new ST_City();
    State = new ST_State();
    Zip = new ST_Zip();
}

Note that there are other semantics involved here (ST_City, ST_State, and ST_Zip) which we won’t go into here.  We’ll populate the ST_Address with the two pieces that Weather Underground requires, city and state, and then publish this type to the docker container:

http://192.168.99.100:5001/publishSemanticType?
  semanticTypeName=ST_Address&instanceJson=
  {
    "City":
      {"City":"Hudson"},
    "State":
      {"State":"NY"}
  }

The microservice, in HOPE terminology, is a “receptor” that is interested in
the type ST_Address.  As implemented in C# (fragment):

public class WeatherForecast : IReceptor
{
  public void Process(ISemanticProcessor proc, IMembrane membrane, ST_Address address)
  {
    string json = Http.Get("http://api.wunderground.com/api/[yourapikey]/forecast/q/" + 
      address.State.State + "/" + 
      address.City.City + 
      ".json");

    var data = WeatherUnderground.FromJson(json);

    var statForecast = data.Forecast.Simpleforecast.Forecastday.Select(d =>
      new
        {
          Month = d.Date.Monthname,
          Day = d.Date.Day,
          Weekday = d.Date.Weekday,
          High = d.High.Fahrenheit,
          Low = d.Low.Fahrenheit,
          Conditions = d.Conditions,
          IconUrl = d.IconUrl,
          MaxWind = d.Maxwind.Mph,
        }).ToList();

    // ...
    // Building the day and night detail forecast is not shown.
    // ...

    Response result = new Response()
    {
      HopeResultWrapper = new WeatherResult()
      {
        StatForecast = statForecast,
        DayForecast = daySummaryForecast,
        NightForecast = nightSummaryForecast,
      }
    };

    // Call back to the host with the result.
    RestCall.Post("http://192.168.0.2/hope/result", result);
  }
}

The response is associated with an XML file that determines the rendering.
Here’s a fragment showing just the first to rows (the day and the icon) of
rendering definition:

hope-5

HOPE renders this into HTML and sends the HTML over an HTML5 websocket to the browser where the page defines this tag:

hope-6

and on receiving the message from host, executes this Javascript:

 ws.onmessage = function (wsevt)
 {
   var msg = wsevt.data;
   $("#appContent").empty();
   $("#appContent").append(msg);
 };

The result is rendered on the browser like this:

hope-2

By changing the rendering to a VerticalGrid we instead get:

hope-3

By changing the rendering XML definition again (not shown, it’s quite long) we can show the results from all three collections — stat, day, and night — to render a more detailed forecast.

hope-4

Of course, in real life, you’ll want to render the results of many microservices.  We’ll look at how that works soon!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s