#591 Request and Response for Haystack Rest.

Hareesh Reddy G.M Mon 5 Mar 2018

Hi All,

Need some clarification on request and response formats of Haystack Rest.

So for response haystack client can specify Accept header and depending on that server can give specified format in response, which comes under Content-negotiation. And default response is formatted as zinc.

Queries:

1) So in request, should client use only zinc format or client can use

formats like 'text/csv' or 'application/json'.

2) If yes, haystack server need to implement HJsonReader and HCsvReader classes,

which can read respective req and change to zinc format to continue with op.

So is this assumption correct/not. If correct, shall we add those additional classes to support read for multiple formats.

Brian Frank Mon 5 Mar 2018

The only full fidelity encodings are JSON and Zinc. CSV is a nice output format, but you can't use that for requests since its not strongly typed.

Since Zinc was the first encoding, its probably the most widely used. But over time, I would expect more systems to migrate to JSON as their primary format.

As both client and server I would suggest always supporting both.

You can query what formats a server supports via the "formats" operation.

Hareesh Reddy G.M Tue 6 Mar 2018

Thaks a lot Brain Frank.

So, JSON request for read op will be something like,

{ "meta": { "ver": "3.0" },

"cols": [{ "name": "id" }],
"rows": [{ "id": "r:A-Meter" }]

}

Is this assumption right ?

Thanks in advance.

Brian Frank Tue 6 Mar 2018

Correct, the examples from the docs:

Read by filter:

ver:"3.0"
filter,limit 
"point and siteRef==@siteA",1000

{
"meta": {"ver":"3.0"},
"cols":[
{"name":"filter"},
{"name":"limit"}
],
"rows":[
{"filter":"point and siteRef==@siteA", "limit":"n:1000"}  
]
}

Read by ids:

ver:"3.0"
id
@vav101.zoneTemp
@vav102.zoneTemp
@vav103.zoneTemp 

{
"meta": {"ver":"3.0"},
"cols":[
 {"name":"id"}
],
"rows":[
{"id":"r:vav101.zoneTemp"},
{"id":"r:vav102.zoneTemp"},
{"id":"r:vav103.zoneTemp"}
]
}

Hareesh Reddy G.M Wed 7 Mar 2018

Thank a lot Brain!

I have a small concern on meta in JSON request.

For Read OP:

We can consider meta as one map as haystack standard.

meta : {"ver":"3.0"}

For WatchSub :

But for watchSub and other ops, where meta consists further details like watchId, limit and so on.

Zinc request:

-------------

ver:"3.0" watchId:"Strwatch" lease:15
id
@A-Meter-KW

So here, how should we consider meta in JSON req,

1) As Single Map

meta : {"ver":"3.0", "watchId":"StrWatch", "limit":"n:5"}

2) As List

meta : [{"ver":"3.0"},{"watchId":"StrWatch"},{"limit":"n:5"}]

if As Map : then it matches with read operation as you said earlier.

if As List : then it does not match with read op, so we should change the read op meta as list like

meta : [{"ver":"3.0"}]

Please help me in this scenario.

Brian Frank Wed 7 Mar 2018

I am not sure I completely understand your proposal.

But Haystack has a one-to-one mapping to JSON:

  • Haystack lists are JSON lists
  • Haystack dicts are JSON objects (maps)

Grid.meta is a Dict so it maps to a JSON object

Stuart Longland Thu 29 Mar 2018

As far as differentiating between grids and dicts; I used the following approach:

If I come across a JSON object that has 3 keys: meta, cols, and rows; with meta being an object, and the others being JSON arrays, then I'm looking at a grid.

Otherwise, it's clearly a dict.

Hareesh Reddy G.M Wed 18 Apr 2018

Hi, 

Need some clarification on empty grid request.

Suppose if we need to send empty grid request for some operation, how it should be ?

I tried this as per documentation, but it's throwing 500 Internal server error.

Case : 1
--------------
ver:"3.0"
empty
--------------

If we send like this, then it will work, so after empty one empty line is required as per reference code.

Case : 2
------------
ver:"3.0"
empty

-------------

And it will also work for this, after empty we can give null, as per zinc N

Case : 3
-------------
ver:"3.0"
empty
N
--------------

So, what's the Haystak standard to send empty grid request ?
Should we continue with Case 2 or 3 or we can change code to make Case 1 work.

Thanks!

Brian Frank Wed 18 Apr 2018

These two things are not the same:

// grid with one "empty column and zero rows
ver:"3.0"
empty

// grid with one one row where empty is null
ver:"3.0"
empty
N

In general the latter would not be used unless you had an application expecting something like that.

You said "throwing 500 Internal server error", but not sure what system you are using nor what request you are trying to make. Would be good to explain the situation and what the full stack trace is

Hareesh Reddy G.M Wed 18 Apr 2018

Thank you Brain!

Yes let's consider watchPoll request.

We are using Haystack-JavaTool kit from Downloads section, and we have been using it.

So, for watchPoll operation request contains meta data, no columns and rows like below.

-------------------------------------
ver:"3.0" watchId:"watch1" refresh:M
-------------------------------------

Then what should be rows and columns

Case 1:

If we send request as below (from postman tool)

------------------------------------
ver:"3.0" watchId:"watch1" refresh:M
empty
--------------------

it throws 500 Internal server error with message :

org.projecthaystack.ParseException: Expected newline not eof [line 2]

org.projecthaystack.ParseException: Expected newline not eof [line 2]
	org.projecthaystack.io.HZincReader.err(HZincReader.java:409)
	org.projecthaystack.io.HZincReader.err(HZincReader.java:405)
	org.projecthaystack.io.HZincReader.verify(HZincReader.java:380)
	org.projecthaystack.io.HZincReader.consume(HZincReader.java:393)
	org.projecthaystack.io.HZincReader.parseGrid(HZincReader.java:305)
	org.projecthaystack.io.HZincReader.readVal(HZincReader.java:85)
	org.projecthaystack.io.HZincReader.readGrid(HZincReader.java:99)
	org.projecthaystack.server.HOp.postToGrid(HOp.java:172)
	org.projecthaystack.server.HOp.onService(HOp.java:56)
	org.projecthaystack.server.HServlet.onService(HServlet.java:119)
	org.projecthaystack.server.HServlet.doPost(HServlet.java:71)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	org.projecthaystack.server.HServletFilter.doFilter(HServletFilter.java:141)


Case 2:

If we send request as below, it runs fine.

----------------------------
ver:"3.0" watchId:"watch1" refresh:M
empty

-------------------------

So we need to know whether it's a grid standard/Haystack standard or it's some internal code error.


Thanks!

Brian Frank Wed 18 Apr 2018

That Java version of HZincReader should allow EOS or newline in that case. But from your stack trace you it looks like you are using an old version. Try using the latest version, and I believe it should handle that case better (and if not, its an easy fix)

Login or Signup to reply.