IRIS Document Database (DocDB)
Tags: beginners, tutorial, datamodel, nosql
Published: 2024-04-14 14:16:09

<p>InterSystems IRIS Document Database (DocDB) offers a flexible and dynamic approach to managing database data.&nbsp;DocDB embraces the power of JSON (JavaScript Object Notation), providing a schema-less environment for storing and retrieving data.</p>
<p>It is a powerful tool, enables developers to bypass a ton of boiler plate code in interaction with existing applications, serialization, pagination and integration. the seamless flow of DocDB with Interoperability Rest services and operations, gives a big leap in API production and management.</p>
<p>for full DocDB documentation <a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GDOCDB_intro" target="_blank">Here</a>. in the context of this article i will showcase a use case&nbsp;in which DocDB will make a perfect fit.</p>
<p><!--break--></p>
<p>Organizations using InterSystems Products like IRIS, Interoperability, TrakCare,... constantly generates agile and new requirements for sharing data through to other systems to consume. while InterSystems offers Built in JSON Adaptor to enable persistent classes to be JSON Serializable on record level, However neither rewriting your application to extent JSON Adaptor is an easy task nor your data of interest is going to be managed always on record level directly from your application classes. here comes DocDB to the picture, because you can build&nbsp;queries over your application code and dump it into DocDB as JSON, ready to ship to consumer apps.</p>
<p>&nbsp;</p>
<p>here is a snippet running any standard IRIS stored procedure in a generic way&nbsp;&nbsp;and saving output as records in json format.</p>
<p>&nbsp;</p>
<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos">        <span class="hljs-comment">//assuming parameters exist as P1,P2,...Pn in context</span>
        <span class="hljs-keyword">set</span> queryData=<span class="hljs-built_in">$lb</span>(<span class="hljs-string">"queryclassname:queryname"</span>,&lt;no of parameters&gt;)
		<span class="hljs-keyword">set</span> queryString=<span class="hljs-built_in">$lg</span>(queryData,<span class="hljs-number">1</span>)
		<span class="hljs-keyword">set</span> paramCount=<span class="hljs-built_in">$lg</span>(queryData,<span class="hljs-number">2</span>)
		<span class="hljs-keyword">set</span> args=<span class="hljs-built_in">$lb</span>()
		<span class="hljs-keyword">for</span> ix=<span class="hljs-number">1</span>:<span class="hljs-number">1</span>:paramCount{
			<span class="hljs-keyword">set</span> var=<span class="hljs-string">"P"</span>_ix
			<span class="hljs-keyword">XECUTE</span> (<span class="hljs-string">"(in,out) SET out=$g(in)"</span>, @var, .y)
			<span class="hljs-keyword">set</span> <span class="hljs-built_in">$li</span>(args,ix)=<span class="hljs-built_in">$s</span>(y'=<span class="hljs-string">""</span>:<span class="hljs-string">""""</span>_y_<span class="hljs-string">""""</span>,<span class="hljs-number">1</span>:<span class="hljs-string">""""</span>_<span class="hljs-string">""""</span>)
			}
		<span class="hljs-keyword">set</span> resultSet=<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%ResultSet</span>).<span class="hljs-built_in">%New</span>(queryString)
		<span class="hljs-keyword">XECUTE</span> (<span class="hljs-string">"(in,out) set out=in.%Execute("</span>_<span class="hljs-built_in">$lts</span>(args)_<span class="hljs-string">")"</span>,resultSet,.scx)
		<span class="hljs-keyword">set</span> sc=scx
		<span class="hljs-keyword">If</span> <span class="hljs-built_in">$$$ISERR</span>(sc) <span class="hljs-built_in">$$$ThrowStatus</span>(sc)
		<span class="hljs-keyword">set</span> columnNo=resultSet.GetColumnCount()
		
		<span class="hljs-keyword">While</span> resultSet.<span class="hljs-built_in">%Next</span>(.sc) {
			<span class="hljs-keyword">If</span> <span class="hljs-built_in">$$$ISERR</span>(sc) <span class="hljs-built_in">$$$ThrowStatus</span>(sc)
			
			<span class="hljs-keyword">set</span> row={}
			<span class="hljs-keyword">for</span> iz=<span class="hljs-number">1</span>:<span class="hljs-number">1</span>:columnNo{
				<span class="hljs-keyword">set</span> columnName=resultSet.GetColumnName(iz)
				<span class="hljs-keyword">do</span> row.<span class="hljs-built_in">%Set</span>(columnName,resultSet.GetDataByName(columnName))
			}
			<span class="hljs-keyword">set</span> sc=<span class="hljs-built_in">..AddRecordToReportResult</span>(ID,row)
			<span class="hljs-keyword">If</span> <span class="hljs-built_in">$$$ISERR</span>(sc) <span class="hljs-built_in">$$$ThrowStatus</span>(sc)
		}</code></pre>
<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">ClassMethod</span> AddRecordToReportResult(doc <span class="hljs-keyword">As</span> <span class="hljs-built_in">%DynamicObject</span>)<span class="hljs-keyword">As</span> <span class="hljs-built_in">%Status</span> {
    <span class="hljs-keyword">set</span> sc=<span class="hljs-built_in">$$$OK</span>
	<span class="hljs-keyword">try</span> {
		<span class="hljs-keyword">if</span> (<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).xNExists(<span class="hljs-string">"PreparedReportDB"</span>)){
			<span class="hljs-keyword">set</span> db=<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).<span class="hljs-built_in">%GetDatabase</span>(<span class="hljs-string">"PreparedReportDB"</span>)
		} <span class="hljs-keyword">else</span> {
			<span class="hljs-keyword">set</span> db= <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).<span class="hljs-built_in">%CreateDatabase</span>(<span class="hljs-string">"PreparedReportDB"</span>)
		}
		<span class="hljs-keyword">set</span> nwRecord=db.<span class="hljs-built_in">%SaveDocument</span>(doc)
		<span class="hljs-keyword">do</span> nwRecord.<span class="hljs-built_in">%Save</span>(<span class="hljs-number">0</span>)
		
		<span class="hljs-keyword">k</span> nwRecord
	}<span class="hljs-keyword">catch</span> err{
		<span class="hljs-keyword">set</span> sc=<span class="hljs-built_in">$$$ADDSC</span>(sc,<span class="hljs-built_in">$$$ERROR</span>(<span class="hljs-string">"5001"</span>,err.DisplayString()))
	}
	<span class="hljs-keyword">return</span> sc
    
}</code></pre>
<p>that is it, your data -whatever it is- is ready to be exposed to consuming apps.</p>
<p>lets take the use case of monitoring integrations, your queries will check the status of your InterSystems interoperability production, the errors, alerts,..</p>
<p>and the data will be saved in a DocDB on intervals.</p>
<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos"><span class="hljs-keyword">Class</span> ProdEye.DataTask <span class="hljs-keyword">Extends</span> <span class="hljs-built_in">%SYS.Task.Definition</span>
{

<span class="hljs-keyword">Property</span> IntervalMinutes <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Integer</span> [ InitialExpression = <span class="hljs-number">5</span> ]<span class="hljs-comment">;</span>
Method OnTask() <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Status</span>
{
	<span class="hljs-keyword">try</span> {
		<span class="hljs-keyword">set</span> packageName=<span class="hljs-built_in">$P</span>(<span class="hljs-built_in">$classname</span>(),<span class="hljs-string">"."</span>,<span class="hljs-number">1</span>)
		
		<span class="hljs-keyword">set</span> targetDocument={}
		
		<span class="hljs-keyword">set</span> ZeroTimeStamp= <span class="hljs-built_in">$$HorologAddSecs</span><span class="hljs-symbol">^EnsUtil</span>(<span class="hljs-built_in">$ztimestamp</span>,-(<span class="hljs-built_in">..IntervalMinutes</span>*<span class="hljs-number">60</span>))
		
		<span class="hljs-keyword">set</span> targetDocument.TimeOfQuery=<span class="hljs-keyword">##class</span>(Ens.DataType.UTC).timeUTC()
		<span class="hljs-keyword">set</span> targetDocument.TimeOfQueryIdx=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"getDateTimeUTCIdx"</span>)
		<span class="hljs-keyword">do</span> <span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetNameSpaceList"</span>)
		<span class="hljs-keyword">k</span> prodArray
		
		<span class="hljs-keyword">do</span> <span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetProductionsList"</span>,.prodArray)
		
		
		<span class="hljs-keyword">set</span> productionObjectList=[]
		
		<span class="hljs-keyword">set</span> currNameSpace=<span class="hljs-string">""</span>
		<span class="hljs-keyword">for</span>  {
			<span class="hljs-keyword">set</span> currNameSpace=<span class="hljs-built_in">$O</span>(prodArray(currNameSpace))
			<span class="hljs-keyword">quit</span>:currNameSpace=<span class="hljs-string">""</span>
			<span class="hljs-keyword">set</span> currProd=<span class="hljs-string">""</span>
			<span class="hljs-keyword">for</span>  {
				<span class="hljs-keyword">set</span> currProd=<span class="hljs-built_in">$O</span>(prodArray(currNameSpace,currProd))
				<span class="hljs-keyword">quit</span>:currProd=<span class="hljs-string">""</span>
				<span class="hljs-keyword">set</span> newProdData=<span class="hljs-built_in">$g</span>(prodArray(currNameSpace,currProd))
				<span class="hljs-keyword">set</span> newProd=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.Production"</span>,<span class="hljs-string">"%New"</span>,currProd,<span class="hljs-built_in">$lg</span>(newProdData,<span class="hljs-number">1</span>),<span class="hljs-built_in">$lg</span>(newProdData,<span class="hljs-number">2</span>))
				
				<span class="hljs-keyword">k</span> compArray
				<span class="hljs-keyword">do</span> <span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentListByProd"</span>,.compArray,currProd,currNameSpace)
				
				<span class="hljs-keyword">set</span> components=<span class="hljs-string">""</span>
				<span class="hljs-keyword">set</span> currComp=<span class="hljs-string">""</span>
				<span class="hljs-keyword">for</span>  {
					<span class="hljs-keyword">set</span> currComp=<span class="hljs-built_in">$O</span>(compArray(currProd,currComp))
					<span class="hljs-keyword">quit</span>:currComp=<span class="hljs-string">""</span>
					<span class="hljs-keyword">set</span> newComp=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.ProductionConfigItem"</span>,<span class="hljs-string">"%New"</span>,currComp,<span class="hljs-built_in">$g</span>(compArray(currProd,currComp)))
					<span class="hljs-keyword">set</span> compId=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentId"</span>,currComp,currProd,currNameSpace)
					<span class="hljs-keyword">set</span> newComp.Type= <span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentType"</span>,compId,currNameSpace)
					<span class="hljs-keyword">set</span> newComp.QueueSize=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentQueueData"</span>,currComp,currNameSpace)
					
					<span class="hljs-keyword">set</span> MessageStats=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentMessageCountAndAvg"</span>,currComp,ZeroTimeStamp,currNameSpace)
					<span class="hljs-keyword">set</span>:<span class="hljs-built_in">$lv</span>(MessageStats) newComp.MessageCount=<span class="hljs-built_in">$lg</span>(MessageStats,<span class="hljs-number">1</span>)
					<span class="hljs-keyword">set</span>:<span class="hljs-built_in">$lv</span>(MessageStats) newComp.MessageAVGProcessingMilliseconds=<span class="hljs-built_in">$lg</span>(MessageStats,<span class="hljs-number">2</span>)
					
					<span class="hljs-keyword">set</span> newComp.JobsStatus=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.JobStatus"</span>,<span class="hljs-string">"BuildPropertyFromList"</span>,<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentJobs"</span>,currComp,currNameSpace))
					<span class="hljs-keyword">set</span> newComp.Errors=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.Log"</span>,<span class="hljs-string">"BuildPropertyFromList"</span>,<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentErrors"</span>,currComp,ZeroTimeStamp,currNameSpace))
					<span class="hljs-keyword">set</span> newComp.Warnings=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.Log"</span>,<span class="hljs-string">"BuildPropertyFromList"</span>,<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentWarnings"</span>,currComp,ZeroTimeStamp,currNameSpace))
					<span class="hljs-keyword">set</span> newComp.Alerts=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.Log"</span>,<span class="hljs-string">"BuildPropertyFromList"</span>,<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentAlerts"</span>,currComp,ZeroTimeStamp,currNameSpace))
					
					<span class="hljs-keyword">do</span> newProd.Components.Insert(newComp)
				}
				
				
				<span class="hljs-keyword">set</span> newProdJSONStr=<span class="hljs-string">""</span>
				<span class="hljs-keyword">do</span> newProd.<span class="hljs-built_in">%JSONExportToString</span>(.newProdJSONStr)
				<span class="hljs-keyword">set</span> newProdJSON={}.<span class="hljs-built_in">%FromJSON</span>(newProdJSONStr)
				<span class="hljs-keyword">do</span>:newProdJSON'=<span class="hljs-string">""</span> productionObjectList.<span class="hljs-built_in">%Push</span>(newProdJSON)
				}
			}
		
		<span class="hljs-keyword">do</span> targetDocument.<span class="hljs-built_in">%Set</span>(<span class="hljs-string">"ProductionList"</span>,productionObjectList)
		<span class="hljs-keyword">if</span> (<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).xNExists(packageName_<span class="hljs-string">".DB.ProdEyeDocument"</span>)){
			<span class="hljs-keyword">set</span> db=<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).<span class="hljs-built_in">%GetDatabase</span>(packageName_<span class="hljs-string">".DB.ProdEyeDocument"</span>)
		} <span class="hljs-keyword">else</span> {
			<span class="hljs-keyword">set</span> db= <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).<span class="hljs-built_in">%CreateDatabase</span>(<span class="hljs-string">"ProdEye.DB.ProdEyeDocument"</span>)
			<span class="hljs-keyword">do</span> db.<span class="hljs-built_in">%CreateProperty</span>(<span class="hljs-string">"TimeOfQueryIdx"</span>,<span class="hljs-string">"%Integer"</span>,<span class="hljs-string">"$.TimeOFQueryIdx"</span>,<span class="hljs-number">0</span>)
			}
		<span class="hljs-keyword">set</span> nwRecord=db.<span class="hljs-built_in">%SaveDocument</span>(targetDocument)
		
		<span class="hljs-keyword">if</span> <span class="hljs-built_in">$$$ISERR</span>(nwRecord){<span class="hljs-built_in">$$$ThrowStatus</span>(nwRecord)}
		
		<span class="hljs-keyword">set</span> nwRecord.ProfileName=<span class="hljs-built_in">$get</span>(<span class="hljs-symbol">^ProdEyeProfileName</span>(<span class="hljs-number">0</span>))
		<span class="hljs-keyword">set</span> nwRecord.TimeOfQueryIdx=targetDocument.TimeOfQueryIdx
		<span class="hljs-keyword">do</span> nwRecord.<span class="hljs-built_in">%Save</span>()
		
		<span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>
	} <span class="hljs-keyword">catch</span> error {
		<span class="hljs-keyword">do</span> BACK<span class="hljs-symbol">^%ETN</span>
		<span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$ERROR</span>(<span class="hljs-string">"5001"</span>,error.AsStatus())
		}
}

}
</code></pre>
<p>now any external consuming app can fetch the data to check productions status, alerts, errors and warnings using a simple&nbsp;InterSystems REST service as the following</p>
<pre class="codeblock-container" idlang="0" lang="ObjectScript" tabsize="4"><code class="language-cls hljs cos">Include Ensemble

<span class="hljs-keyword">Class</span> ProdEye.Prod.ProdEyeRest <span class="hljs-keyword">Extends</span> EnsLib.REST.Service
{

<span class="hljs-keyword">Property</span> PageSize <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Integer</span> [ InitialExpression = <span class="hljs-number">10</span> ]<span class="hljs-comment">;</span>
<span class="hljs-keyword">Property</span> TokenValidationURL <span class="hljs-keyword">As</span> <span class="hljs-built_in">%String</span><span class="hljs-comment">;</span>
<span class="hljs-keyword">Parameter</span> SETTINGS = <span class="hljs-string">"PageSize,TokenValidationURL"</span><span class="hljs-comment">;</span>
XData UrlMap [ XMLNamespace = <span class="hljs-string">"http://www.intersystems.com/urlmap"</span> ]
{
&lt;Routes&gt;
	&lt;Route Url=<span class="hljs-string">"/getdata"</span> Method=<span class="hljs-string">"POST"</span> Call=<span class="hljs-string">"GetData"</span>/&gt;
	&lt;/Routes&gt;
}

Method GetData(pInput <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Library.AbstractStream</span>, Output poutput <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Stream</span>) <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Status</span>
{
	<span class="hljs-keyword">quit</span>:'<span class="hljs-built_in">$IsObject</span>(pInput) <span class="hljs-built_in">$$$OK</span>
	<span class="hljs-keyword">quit</span>:(pInput.SizeGet()=<span class="hljs-number">0</span>) <span class="hljs-built_in">$$$OK</span>
	<span class="hljs-keyword">set</span> paramsObj={}.<span class="hljs-built_in">%FromJSON</span>(pInput.<span class="hljs-keyword">Read</span>())
	<span class="hljs-keyword">set</span> cutoff=paramsObj.cutoff
	<span class="hljs-keyword">set</span> authorisation=paramsObj.Authorisation
	<span class="hljs-keyword">set</span> profilename=paramsObj.profilename
	
	<span class="hljs-built_in">$$$TRACE</span>(<span class="hljs-built_in">..Adapter</span>.IOAddr_<span class="hljs-string">" Profile "</span>_profilename_<span class="hljs-string">" cutoff parameter: "</span>_paramsObj.<span class="hljs-built_in">%ToJSON</span>())
	
	<span class="hljs-keyword">if</span> ('<span class="hljs-built_in">..Authorise</span>(authorisation,<span class="hljs-built_in">..TokenValidationURL</span>)){
		<span class="hljs-keyword">do</span> poutput.<span class="hljs-keyword">Write</span>(<span class="hljs-string">"{""Error"":""Invalid Credentials""}"</span>)
		<span class="hljs-keyword">do</span> <span class="hljs-built_in">..ReportHttpStatusCode</span>(<span class="hljs-number">403</span>)
		 <span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>
	}
	
	<span class="hljs-keyword">if</span> ('<span class="hljs-built_in">..ValidateCutoff</span>(cutoff)){
		<span class="hljs-keyword">do</span> poutput.<span class="hljs-keyword">Write</span>(<span class="hljs-string">"{""Error"":""Invalid Request Parameters""}"</span>)
		<span class="hljs-keyword">do</span> <span class="hljs-built_in">..ReportHttpStatusCode</span>(<span class="hljs-number">400</span>)
		 <span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>
	}
	
	
	<span class="hljs-keyword">try</span>{
		<span class="hljs-keyword">set</span> packageName=<span class="hljs-built_in">$P</span>(<span class="hljs-built_in">$classname</span>(),<span class="hljs-string">"."</span>,<span class="hljs-number">1</span>)
		<span class="hljs-keyword">SET</span> db = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).<span class="hljs-built_in">%GetDatabase</span>(packageName_<span class="hljs-string">".DB.ProdEyeDocument"</span>)
		<span class="hljs-keyword">set</span> restriction=[]
		<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(<span class="hljs-string">"TimeOfQueryIdx"</span>)
		<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(cutoff)
		<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(<span class="hljs-string">"&gt;"</span>)
		
		<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(<span class="hljs-string">"ProfileName"</span>)
		<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(profilename)
		<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(<span class="hljs-string">"="</span>)
		
		<span class="hljs-keyword">SET</span> result = db.<span class="hljs-built_in">%FindDocuments</span>(restriction)
		
		<span class="hljs-keyword">if</span> ((<span class="hljs-built_in">$IsObject</span>(result))&amp;&amp;(<span class="hljs-built_in">$Isobject</span>(result.content))){
			<span class="hljs-keyword">set</span> resultPage={}
			<span class="hljs-keyword">set</span> resultPage.Next=<span class="hljs-number">0</span>
			<span class="hljs-keyword">set</span> resultList=[]
			
			<span class="hljs-keyword">set</span> iter=result.content.<span class="hljs-built_in">%GetIterator</span>()
			<span class="hljs-keyword">for</span> dx=<span class="hljs-number">1</span>:<span class="hljs-number">1</span>:<span class="hljs-built_in">..PageSize</span>{
				<span class="hljs-keyword">set</span> resultItem=iter.<span class="hljs-built_in">%GetNext</span>(.key,.resultItemvalue)
				<span class="hljs-keyword">if</span> <span class="hljs-built_in">$IsObject</span>(resultItemvalue){
					<span class="hljs-keyword">set</span> resultItemvalue={}.<span class="hljs-built_in">%FromJSON</span>(resultItemvalue.<span class="hljs-built_in">%Doc</span>)
					<span class="hljs-keyword">do</span> resultList.<span class="hljs-built_in">%Push</span>(resultItemvalue)
					<span class="hljs-keyword">set</span>:dx&gt;<span class="hljs-number">1</span> resultPage.Next=resultItemvalue.TimeOfQueryIdx
				}
				}
		<span class="hljs-keyword">set</span> resultPage.content=resultList
		
		
		<span class="hljs-keyword">do</span> poutput.<span class="hljs-keyword">Write</span>(resultPage.<span class="hljs-built_in">%ToJSON</span>())
		}<span class="hljs-keyword">else</span> {
			<span class="hljs-keyword">Throw</span> <span class="hljs-built_in">$$$ERROR</span>(<span class="hljs-string">"5001"</span>,<span class="hljs-string">"Error During Processing Data"</span>)
			}
	} <span class="hljs-keyword">catch</span> error {
		<span class="hljs-keyword">do</span> poutput.<span class="hljs-keyword">Write</span>(<span class="hljs-string">"{""Error"":""Error During Processing Data : """</span>_error.AsSystemError()_<span class="hljs-string">""" ""}"</span>)
		<span class="hljs-keyword">do</span> <span class="hljs-built_in">..ReportHttpStatusCode</span>(<span class="hljs-number">500</span>)
		}
	
	<span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>
}

<span class="hljs-keyword">ClassMethod</span> ValidateCutoff(val <span class="hljs-keyword">As</span> <span class="hljs-built_in">%String</span>) <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Boolean</span>
{
	<span class="hljs-keyword">set</span> sc=<span class="hljs-number">1</span>
	<span class="hljs-keyword">quit</span>:+val&lt;=<span class="hljs-number">0</span> <span class="hljs-number">0</span>
	<span class="hljs-keyword">quit</span>:<span class="hljs-built_in">$l</span>(+val)&lt;<span class="hljs-number">5</span> <span class="hljs-number">0</span>
	<span class="hljs-keyword">set</span> valdt=<span class="hljs-built_in">$E</span>(val,<span class="hljs-number">1</span>,<span class="hljs-number">5</span>)_<span class="hljs-string">","</span>_<span class="hljs-built_in">$E</span>(val,<span class="hljs-number">6</span>,<span class="hljs-number">10</span>)
	
	<span class="hljs-keyword">try</span> {
		<span class="hljs-keyword">set</span> date=<span class="hljs-built_in">$zdt</span>(valdt)
		
	}<span class="hljs-keyword">catch</span> err{
			
			<span class="hljs-keyword">set</span> sc=<span class="hljs-number">0</span>
		}
	
	<span class="hljs-keyword">return</span> sc
}

<span class="hljs-keyword">ClassMethod</span> Authorise(val <span class="hljs-keyword">As</span> <span class="hljs-built_in">%String</span>, TokenValidationURL <span class="hljs-keyword">As</span> <span class="hljs-built_in">%String</span>) <span class="hljs-keyword">As</span> <span class="hljs-built_in">%Boolean</span>
{
	<span class="hljs-keyword">quit</span>:<span class="hljs-built_in">$g</span>(val)=<span class="hljs-string">""</span> <span class="hljs-number">0</span>
	<span class="hljs-keyword">if</span> (TokenValidationURL=<span class="hljs-string">""</span>){
		<span class="hljs-keyword">set</span> type=<span class="hljs-built_in">$P</span>(val,<span class="hljs-string">" "</span>,<span class="hljs-number">1</span>)
		<span class="hljs-keyword">set</span> type=<span class="hljs-built_in">$zstrip</span>(<span class="hljs-built_in">$zstrip</span>(type,<span class="hljs-string">"*c"</span>),<span class="hljs-string">"&lt;=&gt;w"</span>)
		<span class="hljs-keyword">quit</span>:<span class="hljs-built_in">$ZCVT</span>(type,<span class="hljs-string">"L"</span>)'=<span class="hljs-string">"basic"</span> <span class="hljs-number">0</span>
		<span class="hljs-keyword">set</span> userpass=<span class="hljs-built_in">$P</span>(val,<span class="hljs-string">" "</span>,<span class="hljs-number">2</span>)
		<span class="hljs-keyword">set</span> userpassDecoded=<span class="hljs-built_in">$system</span>.Encryption.Base64Decode(userpass)
		
		<span class="hljs-keyword">set</span> user=<span class="hljs-built_in">$P</span>(userpassDecoded,<span class="hljs-string">":"</span>,<span class="hljs-number">1</span>)
		<span class="hljs-keyword">set</span> user=<span class="hljs-built_in">$zstrip</span>(<span class="hljs-built_in">$zstrip</span>(user,<span class="hljs-string">"*c"</span>),<span class="hljs-string">"&lt;=&gt;w"</span>)
		<span class="hljs-keyword">set</span> pass=<span class="hljs-built_in">$P</span>(userpassDecoded,<span class="hljs-string">":"</span>,<span class="hljs-number">2</span>)
		<span class="hljs-keyword">set</span> pass=<span class="hljs-built_in">$zstrip</span>(<span class="hljs-built_in">$zstrip</span>(pass,<span class="hljs-string">"*c"</span>),<span class="hljs-string">"&lt;=&gt;w"</span>)
		
		<span class="hljs-keyword">set</span> prodeyeUser=<span class="hljs-keyword">##class</span>(Ens.Config.Credentials).GetValue(<span class="hljs-string">"ProdEyeUser"</span>,<span class="hljs-string">"Username"</span>)
		<span class="hljs-keyword">set</span> prodeyePass=<span class="hljs-keyword">##class</span>(Ens.Config.Credentials).GetValue(<span class="hljs-string">"ProdEyeUser"</span>,<span class="hljs-string">"Password"</span>)
		
		<span class="hljs-keyword">return</span> ((prodeyeUser=user)&amp;&amp;(prodeyePass=pass))
	}<span class="hljs-keyword">elseif</span>(TokenValidationURL'=<span class="hljs-string">""</span>){
		<span class="hljs-keyword">set</span> prodeyeAuthUser=<span class="hljs-keyword">##class</span>(Ens.Config.Credentials).GetValue(<span class="hljs-string">"ProdEyeAuthUser"</span>,<span class="hljs-string">"Username"</span>)
		<span class="hljs-keyword">set</span> prodeyeAuthPass=<span class="hljs-keyword">##class</span>(Ens.Config.Credentials).GetValue(<span class="hljs-string">"ProdEyeAuthUser"</span>,<span class="hljs-string">"Password"</span>)
		
		<span class="hljs-keyword">set</span> tokenVerificationRequest=<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%Net.HttpRequest</span>).<span class="hljs-built_in">%New</span>()
		<span class="hljs-keyword">do</span> tokenVerificationRequest.SetHeader(<span class="hljs-string">"content-type"</span>,<span class="hljs-string">"application/json"</span>)
		<span class="hljs-keyword">do</span> tokenVerificationRequest.SetHeader(<span class="hljs-string">"Authorisation"</span>,<span class="hljs-string">"BASIC "</span>_<span class="hljs-built_in">$system</span>.Encryption.Base64Encode(prodeyeAuthUser_<span class="hljs-string">":"</span>_prodeyeAuthPass))
		<span class="hljs-keyword">set</span> token=<span class="hljs-built_in">$P</span>(val,<span class="hljs-string">" "</span>,<span class="hljs-number">2</span>)
		<span class="hljs-keyword">set</span> data={}
		<span class="hljs-keyword">set</span> data.Token=token
		<span class="hljs-keyword">do</span> tokenVerificationRequest.EntityBody.<span class="hljs-keyword">Write</span>(data.<span class="hljs-built_in">%ToJSON</span>())
		<span class="hljs-keyword">do</span> tokenVerificationRequest.Post(TokenValidationURL)
		
		<span class="hljs-keyword">set</span> response=tokenVerificationRequest.HttpResponse
		<span class="hljs-keyword">if</span> (<span class="hljs-built_in">$IsObject</span>(response) &amp;&amp; <span class="hljs-built_in">$IsObject</span>(response.Data) &amp;&amp; response.StatusCode=<span class="hljs-number">200</span> ){
			<span class="hljs-keyword">set</span> message=<span class="hljs-string">""</span> <span class="hljs-keyword">while</span> 'response.Data.AtEnd {<span class="hljs-keyword">set</span> message=message_response.Data.<span class="hljs-keyword">Read</span>(,.tSC) <span class="hljs-keyword">if</span> 'tSC <span class="hljs-keyword">quit</span>}
			<span class="hljs-keyword">set</span> responseMessage={}.<span class="hljs-built_in">%FromJSON</span>(message)
			<span class="hljs-keyword">if</span> (responseMessage.<span class="hljs-built_in">%IsDefined</span>(<span class="hljs-string">"IsValid"</span>) &amp;&amp; (responseMessage.IsValid=<span class="hljs-string">"1"</span>)){
				<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
			}<span class="hljs-keyword">else</span>{
				<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>
					}
		}<span class="hljs-keyword">else</span>{
			<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>
				}
		}
}

}
</code></pre>
<p>an actual example of a consuming app of the above use case is shared <a href="https://openexchange.intersystems.com/package/prodeye-mobile-app-client-side" target="_blank">here </a>on open exchange. it is a mobile app developed in dart for Flutter framework.</p>
<p>in addition to that, DocDB exposes direct API over all Document Tables , described in detail <a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GDOCDB_rest" target="_blank">Here</a></p>
<p>The Edge that DocDB functionality offers is making API development for information sharing across systems driven by the use case focus while&nbsp;fast tracking and standardizing all the data serialization, staging and integration.</p>
<p>&nbsp;</p>