What views should be suggested by the ComplexObsHandler interface?

As part of TRUNK-2136 we are adding methods to declare supported views within the ComplexObsHandler interface. For this ticket, we need to decide on the views that should be suggested out-of-the-box.

Background

Complex observation handlers allow for new observation data types to be added while hiding the complexity of these new data types from the API. To the OpenMRS API, the complex observation’s value is a “black box” (unknown entity). The API stores a “complex value” reference within the observation which is set by the handler when the observation is created and passed to the handler whenever the observation needs to be retrieved. When retrieving the value for a complex observation, the API needs to allow the client to request different views (i.e., representations) of the value. For example, a client asking for a complex document may want to display the title on one page, a thumbnail view on another page, and render the document itself (or allow it to be downloaded) on yet another page. We refer to these as different views of the observation’s value. Historically, we have supported RAW_VIEW and TEXT_VIEW from within OpenmrsConstants.java and html_view and hyperlink_view within WebConstants.java.

Goal

We want to support the common views (representations) needed by most applications without creating dozens (or more) different views – i.e., we’d like a nice clean list of views that will support 80% or more of needs. So, imagining that a complex observation’s value may be essentially any data type (a simple string, a rich text document, an image, a reference to web resource on a distant server, etc.), we’d like to come up with the typical ways that those values may need to be shown to users and then condense those to a short list of relatively clear choices. These will become constants within the ComplexObsHandler interface (modules supplying their own complex observation handlers are free to use custom views as needed). The constants should follow a convention (e.g., lowercase without the redundant “_view” suffix in the value).

Potential views

  • raw – we definitely need this one, requests the raw value for display or download

  • title – plain text short title describing the value (e.g., “ENT Note” or “Chest X-ray”… if you were printing the observation value in the newspaper, this would be the headline). Should not include observation date, since that is already available through the API.

  • text – plain text representation of the value (e.g., a plain text version of a binary document)

  • html – rich text representation of the value (e.g., a document with simple HTML tags included)

  • preview – rich text preview (e.g., a thumbnail of an image or an icon for a document)

  • uri – a URI to the value (e.g., a REST resource or a hyperlink to a separate PACS system for an x-ray)

Does this cover at least 80% of typical representations needed for values? Should any of these be removed/replaced/renamed?

As discussed in TRUNK-2136, the “download” view seems to be useless. It is used in the “HTML Form Entry” module, but the fact is that no handler implements it and it finally falls through to default view (that is a raw view). And it works fine.

1 Like

(Based on discussion with @wyclif):

For TextHandler, I think that RAW_VIEW should produce the same data as TEXT_VIEW; any complaints?

Also, we talked about whether it’s necessary to introduce WebTextHandler; perhaps yes (for the download purposes).

I mean, if I’m not much mistaken, only such a web handler has the info necessary to construct valid URIs, hasn’t it (i.e. content directory mapping)?

Yes, for a text value, raw and text are the same thing… but, then again, …

What is the purpose of a “TextHandler”? Why wouldn’t someone just use the built-in text datatype? I don’t believe we need complex handlers for datatypes that are already handled by existing, simple datatypes – i.e., we don’t need a TextHandler any more than a DateHandler or a NumericHandler. Maybe “TextHandler” is doing something more than is done by a observation with datatype text?

I still can’t get the difference between raw and text view, can you give a good example where raw and text data would be different?

I don’t understand the use case for a “text handler”, since we already have a text datatype; however, I can imagine examples of text-based complex observations that would differ between raw and text views:

  • SomeDocumentHandler – handles documents with or without simple markup. raw view returns original documents, text view always returns plain text (any markup stripped out)

  • SomePdfHandler – raw returns binary version of PDF, text returns plain text extracted from PDF without images or formatting.

  • SomeCultureResultHandler – raw returns culture results as a list of observations, text returns a plain representation of the same information.

  • SomeBloodPressureHandler – raw returns systolic & diastolic blood pressures along with patient position, text returns something like “120/80”.

Guys, I think I’ve found the reason for something like “download” view in the (web) code after all. The thing is that in a browser, e.g. for the WebImageHandler, you may either open another tab/window for an image or the servlet may add Content-Disposition header to cause opening of download window. The content itself is still the same.

So how about that? Should I treat it as app-specific view (or something completely different) or shall we somehow pull/map this in/on our well-known views?

UPDATE: I’ve thought it through and I think that that’s not something that should be controlled by view. I’ll change this a bit; for images & text, the content will be opened in browser; for data, save-as window shall be invoked by adding the Content-Disposition header.

How’s that?

@vencik, I believe the distinction you are making is whether or not the HTTP response for the raw value of complex observation will contain Content-Disposition: attachment; filename="somefile.txt". I believe this goes outside of the contract between the API and complex observation handler (i.e., ComplexObsHandler), since the handler’s job is to deliver the value through the API (in response to the API or a client of the API asking for the ComplexData. Delivering those data (via an HTTP response of a servlet or for a REST API call) exists outside of the complex obs handler conversation.

So, for example, if you were calling the REST API to get the raw value of a complex observation, it would be up to the REST API to decide how to deliver the raw values for complex observations. It could always respond with a Content-Disposition header, never use the header, or leave it up to the client by providing a download parameter or URL extension (e.g. obs/12345 vs. obs/12345/download). The decision whether or not to include the Content-Disposition header in the HTTP response would be up to the REST API and the complex obs handler would just be delivering the raw value in either case.

As an aside, ComplexData should probably include a mime type property.

It would be nice; shall I add it in scope of the issue? I can distinguish between images and other binary content without it (by the complex data type info), but it would be much better indeed to have proper content type identification (not to mention that proper content MIME type should be set in the HTTP response).

Sure! mimeType would be a good addition to ComplexData.