Best practices to produce JSON from NotesViews or DocumentCollections - json

I'm working on a custom control that will be fed by JSON content and I'm trying to find the best approach to produce and consume it.
Let say the JSON could be from:
Notes View (all documents)
Notes View (subset of documents based on a category or filter)
Notes Document Collection (from database.Search or database.FTSearch)
What I have on my mind is to define some Custom Properties where I can define:
URL that produces the JSON
Object
etc.
So far I'm considering:
REST Service control from ExtLib
XAgent that produces JSON
Domino URL ?ReadViewEntries and OutputFormat=JSON
Does anyone knows if the JSON object loaded in memory has a size limit?
Any suggestion will be appreciated.

Definitely go for the REST Service control from the Extension Library, offers by far the best combination of flexibility vs performance vs development time.
Matt

What about creating the JSON in the view itself and then just read the column values? http://www.eknori.de/2011-07-23/formula-magic/

If you want to parse the json object using ssjs, you can fetch it using an URLConnection and put the resulting object into a repeat control using the eval statement.

Related

Create JSON Object in React.js from Rest Service

I am looking for either guidance or a good example where I can map data coming from rest services to JSON "type" object which can then be used in a number of different react components.
The JSON Object will be used to map data from a few different rest services, which essentially hold very similar data which makes it better to use one object and then to bind the data to the respective React Components.
I am fairly new to React.JS and I have googled around to find a data mapper to JSON from Rest Service example.
Can anyone help?
You typically don't have to do too much, at least on the front end side. As long as the REST endpoint can return JSON responses you'll be fine. Just make sure you set the appropriate Content-Type headers in the request. Note that setting the header doesn't guarantee a JSON response, the server has to be able to send it in that format.
If you're creating the REST service yourself, you have many options. If you're using node, you can simply return a javascript object. If you're using some other language like Java, C#, etc., they come with libraries that can serialize objects into JSON for you. I use JSON.net when working with C#. In these cases, because the data will be returned as a string, you'll just need to JSON.parse() it upon receiving it and then set it to the appropriate React component's state.

Returning MarkLogic EVAL REST service output as JSON

I am working on a demo using MarkLogic to store emails exported from Outlook as XML, so that they stay searchable and accessible when I move away from Outlook.
I am using an AngularJS front-end calling either the native MarkLogic REST services of own REST services written in JAVA using Jersey.
MarkLogic SEARCH REST service works very well to get back a list of references to documents based on various search criteria, but I also want to display information stored inside the found documents.
I would like to avoid multiple REST calls and to get back only the needed information, so I am trying to use the EVAL REST service to run an xQuery.
It works well to get XML back (inside a multipart/mixed message) but I don't seem to be able to get JSON instead which would be much more convenient and is very easy with most other MarkLogic REST services.
I could use "json:transform-to-json()" in my xQuery or transform the XML to JSON in my JAVA code, but that does not look very elegant to me.
Is there a more efficient method to get where I am trying to go ?
First, json:transform-to-json seems plenty elegant to me. But of course it's not always the right answer.
I see three options you haven't mentioned.
server-side transforms - REST search supports server-side transforms which transform each document when you perform a bulk read by query. Those server-side transforms could generate any json you need.
search extract-document-data - this the simplest way to extract portions of documents. But it seems best if your documents are json to match your json response. Otherwise you get xml in your json response . . . unless you're ok with that.
custom search snippets - another very powerful way to customize what search returns
All of these options don't require the privileges that eval requires, which is a very good thing. Since eval allows execution of arbitrary code on your server, it requires special privileges and should be used with great care. Two other options before you use eval are (1) custom xquery installed in an http server, and (2) REST extensions.
The answers from Sam are what I would suggest. Specifically I would set a search option for search-extract-document-data (This is a search API option. If you are posting the request, then you can add the option in the XML you post back. If you are using GET, then you need to register the option ahead of time and call it. Relevant URLs to assist:
https://docs.marklogic.com/guide/rest-dev/search#id_48838
https://docs.marklogic.com/guide/search-dev/appendixa#id_44222
As for json.. ML8 will transform content. Use the accept-header or just add format=json to your results...
Example - xml which is what my content is stored as:
http://localhost:8000/v1/search?q=watermellon
...
<search:result index="1" uri="/sample/collections/1.xml" path="fn:doc("/sample/collections/1.xml")" score="34816" confidence="0.5982239" fitness="0.6966695" href="/v1/documents?uri=%2Fsample%2Fcollections%2F1.xml" mimetype="application/xml" format="xml">
<search:snippet>
<search:match path="fn:doc("/sample/collections/1.xml")/x">
<search:highlight>watermellon</search:highlight>
</search:match>
</search:snippet>
</search:result>
...
Example - json which is what my content is stored as:
http://localhost:8000/v1/search?q=watermellon&format=json
...
"index":1,
"uri":"/sample/collections/1.xml",
"path":"fn:doc(\"/sample/collections/1.xml\")",
"score":34816,
"confidence":0.5982239,
"fitness":0.6966695,
"href":"/v1/documents?uri=%2Fsample%2Fcollections%2F1.xml",
"mimetype":"application/xml",
"format":"xml",
"matches":[
{
"path":"fn:doc(\"/sample/collections/1.xml\")/x",
"match-text":[
{
"highlight":"watermellon"
}
]
}
]
}
...
For real heavy-lifting, you can use server-side transforms as in Sam's description. One note about this. Server-side transformations are not part of the search API, but part of the REST API. Just mentioning it so you have some idea of which tool you are using in each case..

What are developers their expectations when receiving a JSON response from a server

I have java library that runs webservices and these return a response in XML. The webservices all revolve around giving a list of details about items. Recently, changes were made to allow the services to return JSON by simply converting the XML to JSON. When looking at the responses, I saw they're not as easy to parse as I thought. For example, a webservice that returns details about items.
If there are no items, the returned JSON is as follows:
{"ItemResponse":""}
If there is 1 item, the response is as follows (now itemResponse has a object as value instead of a string):
{"ItemResponse":{"Items":{"Name":"Item1","Cost":"$5"}}}
If there two or more items, the response is (now items has an array as value instead of an object):
{"ItemResponse":{"Items":[{"Name":"Item1","Cost":"$5"},{"Name":"Item2","Cost":"$3"}]}}
To parse these you need several if/else which I think are clunky.
Would it be an improvement if the responses were:
0 items: []
1 item: [{"Name":"Item1","Cost":"$5"}]
2 items: [{"Name":"Item1","Cost":"$5"},{"Name":"Item2","Cost":"$3"}]
This way there is always an array, and it contains the itemdata. An extra wrapper object is possible:
0 items: {"Items":[]}
1 item: {"Items":[{"Name":"Item1","Cost":"$5"}]}
2 items: {"Items":[{"Name":"Item1","Cost":"$5"},{"Name":"Item2","Cost":"$3"}]}
I'm not experienced in JSON so my question is, if you were a developer having to use these webservices, how would you expect the JSON resonse to be formatted? Is it better to always return a consistent array, even if there are no items or is this usually not important? Or is an array not enough and do you really expect a wrapper object around the array?
What are conventions/standards regarding this?
Don't switch result types, always return an array if there are more items possible. Do not mix, for 1 item an object for more an array. That's not a good idea.
Another best practise is that you should version your API. Use something like yoursite.com/api/v1/endpoint. If you don't do this and you change the response of your API. All your client apps will break. So keep this in mind together with documentation. (I've seen this happen a lot in the past..)
As a developer I personally like your second approach, but again it's a preference. There is no standard for this.
There are several reasons to use json:
much more dense and compact: thus data sent is less
in javascript you can directly access those properties without parsing anything. this means you could convert it into an object read the attributes (often used for AJAX)
also in java you usually don't need to parse the json by yourself - there are several nice libs like www.json.org/java/index.html
if you need to know how json is build ... use google ... there tons of infos.
To your actual questions:
for webservices you often could choose between xml and json as a "consumer" try:
https://maps.googleapis.com/maps/api/place/textsearch/json
and
https://maps.googleapis.com/maps/api/place/textsearch/xml
there is no need to format json visually - is it not meant for reading like xml
if your response doesn't have a result, json-service often still is giving a response text - look again at the upper google map links - those are including a response status which makes sense as it is a service.
Nevertheless it's the question if it is worth converting from xml to json if there isn't a specific requirement. As Dieter mentioned: it depends on who is already using this service and how they are consumed ... which means the surrounding environment is very important.

Can OData be made to return CSV or URL?

I'm new to OData so I'm sorry if this is a bad question, but I fail to find an answer.
I have a bunch of OData tables, and I would like to provide an option for the user to get the data as a CSV-file.
Now I know OData only supports Atom and JSON, but is there any way to make it return a filestream, or a URL?
I was thinking a URL could direct to a REST-service (not OData) that simply returns a filestream, if filestream directly from OData is impossible.
Any thoughts or ideas are appreciated!
I'm not totaly sure why you want to use oData. But oData essentially means to publish any kind of data in JSON/atom standard format - not CSV.
If you have controll over your oData source you could modify an oData Producer to output CSV filestreams instead of JSON/atom files.(But you wouldn't have a real oData feed anymore)
You could also set up any oData Consumer (you can find those at odata.org) to read your oData source and display it as CSV.
If you choose a server side solution(PHP/JSP/ASP etc.) it should be rather simple to loop through the results of a request and add seperators inbetween.

Consuming JSON WCF on Silverlight

I'm want to try changing a SOAP WCF to accept requests and return results in JSON format to make the data traffic less bulky.
I see that JSON requests functions looks like this:
wcfClient.OpenReadAsync(http://yourUrl.com/wcf/service1.svc/GetEmployees)
and do the regular SOAP requests functions instead that looks like :
wcfClient.GetEmployeesAsync();
1) For JSON results, do you need to parse them into an object or is it automatically parsed like SOAP?
2) Is there a way to do this without doing too much work like changing every single WCF calls in the project to looks "JSON-ish"?
To complement Davut's answer - WCF does support building RESTful services, although I agree that the ASP.NET Web API framework in general easier to use than WCF. JSON.NET is a great library, and it has nice deserialization capabilities (e.g., it can easily take the JSON which represent the list of Employee objects and convert them into the actual List<Employee> instance)
But for completeness sake, if you want to use a "normal" WCF client to access WCF-based services which return JSON, you can do it. It's not too straightforward, but you can do that by using a new encoder and behavior which does the conversion. The post at http://blogs.msdn.com/b/carlosfigueira/archive/2010/04/29/consuming-rest-json-services-in-silverlight-4.aspx talks more about it, and has a pointer to a code sample.
In short, it's possible to consume JSON using a WCF client in Silverlight, but due to its complexity it's usually not done, and Davut's option (use a HTTP client such as WebClient to download JSON, then a library such as JSON.NET to parse it into objects) is preferred.
Firstly the idea "make the data traffic less bulky." is good.
Especially for Mobile devices. Beside this don't think that WCF xml causes network issues for PC. XM is the one of most compressible format. By WCF binary it goes as compressed.
For "Is there a way to do this without doing too much work?"
Yes there is a way name on it RESTFul Services(Restless Services). Now Microsoft directly support it by WEBApi.
Also you may use ODATA for filtering,ordering operations
Here are some links,
http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webgetattribute.aspx
http://blogs.msdn.com/b/rjacobs/archive/2010/06/14/how-to-do-api-key-verification-for-rest-services-in-net-4.aspx
ODATA
http://www.odata.org/documentation/uri-conventions#FilterSystemQueryOption
A few practice notes,Some restrictions:
EntityFrameWork entities derived from EntityObject which has IsReferenceType attribute doesn't allow you to JSON serialize. ( I produced POCO objects using an automapper mapped them and serialized json)
WEBAPI support you much think such as WebGet,WebInvoke GetXML Give JSON ,ODATA features(just select and format not allowed.)
Note:In your web request's header you should accept text/json to get really json.
"For JSON results, do you need to parse them into an object or..."
I can say you should try JSON.NET it's portable library works everywhere. When you deserialize with a generic function it returns you the collection you expect.
Hope it helps someone. While discovering these stackoverflow helped me like an assistant.