Genii Weblog


Civility in critiquing the ideas of others is no vice. Rudeness in defending your own ideas is no virtue.


Fri 28 Aug 2020, 02:26 PM
Inline JPEG image
 
It is a fairly longstanding truism that software platforms live and die by the applications, extensions, and integrations written for them. OS/2 was a kick butt operating system, but could not keep the ecosystem going. Notes/Domino has been an amazing platform for decades, but has struggled in part because too many times, there wasn't an integration to Notes where there was to Outlook. (There are plenty of other examples, but these are more central to this community.)
 
But is this still a requirement? The world has changed in a lot of ways, and the ecosystems have moved outside of the platforms to some degree. Obviously, as an ISV, I'd like it to still be true that ISVs are critical to a platform's success, but wanting it is not the same as it being true. HCL is doing a ton of great work on the products, but they seem a little disinterested in other people writing products that use Domino as a backbone, for example. They seem fairly convinced that the products will live out there somewhere, and that what is needed is a way to get the data in and out. Is that enough?
 
Thoughts? I am genuinely curious what people think.
 

Copyright © 2020 Genii Software Ltd.

Tags:

Thu 27 Aug 2020, 08:17 PM
 
Inline JPEG image
 
In my earlier post, Quick primer on JSON-RPC, I promised to post videos showing some features of our new Exciton Boost, due out next week. A few days ago, I followed this up with a first at the REST API in REST Revisited. It is time to demonstrate the RPC API, but I want to start with a little context.
 
In the modern world, both server and client are very powerful. Processing power is abundant, but there are still decisions to be made about where processing should happen. These decisions may be based on security, on related data available, on where you want business logic to live, and many other reasons. In this simple demo, I should how you can use powerful RPC methods on data as it is being pulled out of Domino, even without changing the data on Domino. So, the logic is done there, but the results are passed to the client. You can use similar logic to change the data in Domino, or to change data as it is added to Domino, but we'll look at use cases for both in another demo.
 
 
HTML and JavaScript used in the demo. I hardcoded the UNID in this, but the logic would work the exact same way of I had walked a view and read a document from there. Note that there is no explicit authentication code because this lives in the same database and the session handles that.
 
<!DOCTYPE html>
<html>
<body>
 
<script>
const genHTM =   { jsonrpc: "2.0",  
                   method: "rtc.generateHTML",
                   params: [ "Everything", "XHTML", "CSSBorders=yes Generation=fragment " ],
                   id: 1
                 };
 
const glossary = { jsonrpc: "2.0",
                   method: "rtc.linkMatching",
                   params: [ "", "MedXref.nsf", "Medical Glossary", "Term", "Definition",
                             "Fieldname=Definition Hotspot=Mouseover Style=Highlight " ]
                 };
 
const links =    { jsonrpc: "2.0",
                   method: "rtc.linkMatching",
                   params: [ "", "MedXref.nsf", "MedLinks", "Term", "Link", "SingleMatch='Yes' " ]
                 };
 
function doIt(num) {
 
switch(num) {
  case 1:
    var data = [genHTM];
    break;
  case 2:
    var data = [glossary, genHTM];
    break;
  case 3:
    var data = [glossary, links, genHTM];
    break;
  default:
    var data = [genHTM];
    break;
 
  method: 'POST', 
  mode: 'same-origin',
  cache: 'no-cache',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
 document.getElementById("demo").innerHTML = data[0].result;
})
.catch((error) => {
  console.error('Error:', error);
});
 
};
</script>
<button type="button" style="border-radius: 6px;" onClick="doIt(1);">Get the document as is</button><br>
<button type="button" style="border-radius: 6px;" onClick="doIt(2);">Get the document and apply the glossary on the way out</button><br>
<button type="button" style="border-radius: 6px;" onClick="doIt(3);">Get the document and apply the glossary and link matcher on the way out</button><br>
 
<p id="demo"></p>
 
</body>
</html>
 
 

Copyright © 2020 Genii Software Ltd.

Tags:

Tue 18 Aug 2020, 02:28 PM
 
Inline JPEG image
 
Last week in my post, Quick primer on JSON-RPC, I promised to post videos showing some features of our new Exciton Boost, due out this month. My tendency is to focus on the whiz-bang, but with APIs, some of the most important things are those that appear simple. With that in mind, my first video is on the REST API that is included with Exciton Boost. The REST API features a lot of power packed in a simple package. As you might expect from our products, high fidelity rendering and round-trip abilities stand out, but so do smaller, less showy aspects.
 
Since most of this happens under the covers, keep these in mind while you watch the video:
  • JSON parser allows single document (object) processing and discarding to minimize memory overhead. Not an issue with 25 small documents, but a huge issue with a thousand documents using extensive rich content.
  • Filtered items allow you to retrieve only the items you need from an API that provides too much.
  • Renamed items allow you to map item names in the JSON object to different Notes item names.
 
And remember, it's always Beer O'Clock somewhere...
 
 
 
Code I used in the demo
 
Sub Initialize
   DimAs New NotesSession
   Dim http As NotesHTTPRequest
   Dim json_val As String
   Dim ret As String 
 
   ' *** Retrieve the Beer data from public REST API
   Set http = s.CreateHTTPRequest()
   http.PreferStrings = True
   json_val = CStr(http.get("https://api.punkapi.com/v2/beers"))
 
   ' *** Post the Beer data to Domino db
   Call http.Setheaderfield("Authorization", AUTHSTRING)
   Call http.Setheaderfield("X-Items-List""Name,Id,Description,food_pairing=Pairing,brewers_tips=Tips,tagline")
   ret = http.post("http://localhost/BeerOClock.nsf/api/boost/documents", json_val)
   Print ret
End Sub
 

Copyright © 2020 Genii Software Ltd.

Tags:

Fri 14 Aug 2020, 12:20 PM
 
Inline JPEG image
Over the next few weeks, I will be demonstrating our new Exciton Boost product, which combines a high fidelity REST API and a powerful JSON-RPC API. This is just a quick primer to explain how JSON-RPC works for those unfamiliar with it.
 
When people talk about web APIs, they tend to think first about REST APIs. REST APIs are straightforward and recognizable, usually using JSON or XML as the payload (i.e., the stuff that will get shoved into or yanked out of the remote system), and always using HTTP as the transport mechanism. Let's assume that you either know what a REST API is or can utilize those handy dandy search engines if you are curious.
 
Leaving aside exactly how a REST API works and what it looks like, a core concept is that data transfer is easy and aligns well with CRUD (Create/Read/Update/Delete) operations. The programmatic effort of doing something with the data is left to the client. This makes REST APIs simple and clean, but it can make the client app more complex and lead to a lot of data going back and forth, It also means that data has to leave the server to be processed. Attempting to force actions that will happen on the server into a REST API means ignoring concepts such as resources or forcing the limited HTTP verbs to do stuff they aren't supposed to.
 
An alternative to the REST API is the RPC (Remote Procedure Call). This is a much older concept, but also much more wide open. The client sends instructions to the server for the server to do processing. When you tell Notes to do something to a Domino database, it is actually sending NRPC (Notes Remote Procedure Calls) to the Domino server. In the web world, there are many custom APIs, but a growing number adhere to the JSON-RPC standard.
 
JSON-RPC is built upon the concept of methods. It is not tied to HTTP, though it is often used with HTTP or gRPC. In either case, the request is formatted as a JSON value with either a single request object or an array of request objects. A sample request object could look like this:
 
{
  "jsonrpc": "2.0",
  "method": "addPerson",
  "params": {"firstName": "Ben", "lastName": "Langhinrichs"},
  "id": 1
}
 
or like this
 
{
  "jsonrpc": "2.0",
  "method": "addPerson",
  "params": ["Ben", "Langhinrichs"],
  "id": 1
}
 
In all requests, the jsonrpc item is required and must be exactly "2.0". The method item is also required, and should be a valid method recognized by the server API. The params item, whether an object with named parameters or a positional array of parameters, is required only if the method requires parameters. The id item is required of a return value is defined and wanted. If there is no id item, there will be no response object unless the JSON could not be parsed. In this case, the Person is assigned an employee identifier which is returned, so the response object would be:
 
{
  "jsonrpc": "2.0",
  "result": "BL345A",
  "id": 1
}
 
The response object will always have either a result or error, and will always include an id  to tie it back to the request. An error might look like this if I spelled thee method name incorrectly
 
{
   "jsonrpc": "2.0",
   "error": {
      "code": -32601,
      "message": "Request method does not exist or is not available: addPreson"
  },
  "id": 1
}
 
In future posts, I'll show more real life examples so you can see how JSON-RPC works with batch requests, and ways in which the REST API differs from Domino Access Services.

Copyright © 2020 Genii Software Ltd.

Tags: