New post

Find

Article
· Feb 11 9m read

Using REST API, Flask and IAM with InterSystems IRIS - Part 1 - REST API

Using Flask, REST API, and IAM with InterSystems IRIS

Part 1 - REST API

 

Hello

In this article we will see the implementation of a REST API to perform the maintenance of a CRUD, using Flask and IAM.

In this first part of the article we will see the construction and publication of the REST API in Iris.

First, let's create our persistent class to store the data. To do this, we go to Iris and create our class:

Class ERP. Client Extends (%Persistent, %Populate, %XML.Adaptor)

{

 

Property name As %String;

 

Property age As %Integer;

 

}

 

Ready. We already have our persistent class created and ready to receive data. Now let's create our REST API.

When we talk about REST, we are talking about the HTTP protocol and its verbs. HTTP verbs are methods that define the operation that the client wants to do. Some examples of HTTP verbs are:

  • GET: Requests a specific resource and returns only data. It is the standard for submitting data when submitting an HTTP form. 
  • POST: Submits data to a resource, changing states of a resource present on the server. It is used to send information to be processed, such as creating a product or a customer. 
  • HEAD: Similar to the GET method, however it does not require the body of the response.
  • PUT: Replaces all current renditions of the target resource with the request's data payload.
  • DELETE: Deletion.

As a response to the verbs we have, the status codes indicate the result of the request. For example, 200 indicates that the request was successful.

Iris implements REST in a very easy and robust way. The following documentation provides all the information you need to create a REST API: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GREST

Let's then assemble the code of our REST API to perform basic maintenance on our ERP class. Customer. for this we will create a class that extends from %CSP. REST:

Class Rest.Servico Extends %CSP. REST

{

 

XData UrlMap

{

<Routes>

        <route url="/customer" method="POST" call="include" cors="true"/>

        <Route Url="/customer/:key" Method="PUT" Call="Change" Cors="true"/>

        <Route Url="/client/:key" Method="DELETE" Call="Delete" Cors="true"/>

        <Route Url="/customer/:key" Method="GET" Call="Search" Cors="true"/>

        <Route Url="/client" Method="GET" Call="List" Cors="true"/>

    </Routes>

}

 

ClassMethod Include() The %Status

{

             

              From ##class(%REST. Impl).%SetContentType("application/json")

             

    Set payload = %request. Content.Read()

    Set objJSON=##Class(%DynamicAbstractObject).%FromJSON(payload)

       

    Set objCustomer=##Class(ERP. Client).%New()

    Set objClient.name=objJSON.name

    Set objClient.age=objJSON.age

    Set st=objClient.%Save()

    If 'st

    {

                  From ##class(%REST. Impl).%SetStatusCode("404") Quit $$$OK

 

    }

   

              From ##class(%REST. Impl).%SetStatusCode("200")

 

    return $$$OK

}

 

ClassMethod Change(key As %Integer) As %Status

{

             

              From ##class(%REST. Impl).%SetContentType("application/json")

 

    Set payload = %request. Content.Read()

    Set objJSON=##Class(%DynamicAbstractObject).%FromJSON(payload)

       

    Set objCustomer=##Class(ERP. Client).%OpenId(key)

    If '$IsObject(objClient)

    {

                  From ##class(%REST. Impl).%SetStatusCode("404") Quit $$$OK

 

    }    

   

    Set objClient.name=objJSON.name

    Set objClient.age=objJSON.age

    Set st=objClient.%Save()

    If 'st

    {

                  From ##class(%REST. Impl).%SetStatusCode("500") Quit $$$OK

 

    }   

   

              From ##class(%REST. Impl).%SetStatusCode("200")

 

    return $$$OK

}

 

ClassMethod Delete(key As %Integer) As %Status

{

              From ##class(%REST. Impl).%SetContentType("application/json")

       

    Set st=##Class(ERP. Client).%DeleteId(key)

    If 'st

    {

                  From ##class(%REST. Impl).%SetStatusCode("404") Quit $$$OK

 

    }   

   

              From ##class(%REST. Impl).%SetStatusCode("200")

 

    return $$$OK

}

 

ClassMethod Search(key As %Integer) As %Status

{

       

    From ##class(%REST. Impl).%SetContentType("application/json")

             

    Set objCustomer=##Class(ERP. Client).%OpenId(key)

    If '$IsObject(objClient)

    {

                  From ##class(%REST. Impl).%SetStatusCode("404") Quit $$$OK

 

    }

   

              From ##class(%REST. Impl).%SetStatusCode("200")   

   

    Set objJSON={}   

    Set objJSON.id=key

    Set objJSON.name=objectClient.name

    Set objJSON.age=objCustomer.age

             

              Write objJSON.%ToJSON() 

 

    return $$$OK

}

 

ClassMethod List() As %Status

{

              From ##class(%REST. Impl).%SetContentType("application/json")          

                                         

              Set result=##class(%ResultSet).%New("%DynamicQuery:SQL")

 

              Set st=result. Prepare("select id, name, age from ERP. Client")

    If 'st

    {

                  From ##class(%REST. Impl).%SetStatusCode("500") Quit $$$OK

 

    }        

              Set st=result. Execute()

   

    Set objJSON={}

    Set clients=[]

             

              While result. Next(.st) {

                           

                            Set objCliente={}

                            Set objClient.id=result.%Get("ID")                                          

                            Set objClient.name=result.%Get("name")             

                            Set objectCustomer.age=result.%Get("age")       

                            From Customers.%Push(objectCustomer)

              }

       

              From ##class(%REST. Impl).%SetStatusCode("200")

             

              Set outputa={}

              Set out.customers=customers

             

              Write output.%ToJSON()

 

    return $$$OK

}

 

}

Notice the part of the code that defines the URLs (UrlMap) where we have the URL called, the verb (Method) triggered, and the method of the code that should be called. It is very easy to understand each of the calls made and the association of the call with the HTTP verb.

Now that we've created our class, let's set up a web application in the iris so that this application does the REST service we want to provide. To do this, we go to the Administration->System Administration->Security->Applications->Web Applications Portal and we will create a new application:

 

Enter the name of the application (/rest/service), the Namespace where the REST class was created, check the Activate application box. Select the REST option and enter the Dispatch class. Check the Password option under Methods for Authentication and save the setting.

Our REST class is published and ready to be consumed. Simple as that!

We're going to use Postman to do some testing on our API. The first test is to see if we can retrieve the customer list.

Let's open Postman, and in the address bar we'll enter the URL of our API: http://<ip_addr>/<config_iris>/rest/service/customer. Enter the authentication data (username and password) to access the API in the Authorization tab:

 

 

Now select the desired verb, GET, and submit the request. This setting will trigger the List method. And then we have as a response an HTTP 200 status and the list of clients.

We can make an inclusion with the call using the POST verb and creating a body for our request. To do this, go to the Body tab and enter the payload that will be sent (in our example {"name":"Pierre", "age":"45"}). Click Send and see the response (HTTP status 200):

 

 

Now we have Pierre's record created in our class. We can fetch the record with the GET by passing the record ID number:

Note that now, in the URL, we enter the ID of the desired record. This causes our API to call the Search method.

So we have our persistent class created, our REST API developed and published in Iris, and it can be safely consumed.

In the next part of this article we will see how we can consume this API through a FLASK application.

Discussion (0)1
Log in or sign up to continue
Question
· Feb 11

Intersystems Reports (Logi Reports) - Does it merge multiple PDFs?

We currently use a combination of Ghostscript and ImageMagick to accomplish our PDF requirements.  These products are ceating memory/cpu issues when merging large PDFS.  I am trying to find out if Intersystems Reports can handle our requirements (see below).

 

   

Magick 7.0.10 - Ghostscript 9.53.2
Magick 7.0.10 - Ghostscript 10.04
Does Not Work

Function

Image manipulation

Required Software

Create/print Requisition

PDFToPCL

Ghostscript + ImageMagick using convert command

Create/print Requisition

PDFToPCL

Ghostscript + ImageMagick using convert command

ConvertImgToPDF

 

Ghostscript + ImageMagick using convert command

ConvertPDFToPNG

 

Ghostscript

ConvertPDFToText

 

Ghostscript

MergePDFS

 

Ghostscript

PDFToPCL

 

Ghostscript + ImageMagick using convert command

PrintABN

s cmd="i:\pdfPrintX\PDFtoPrinter

PDFtoPrinter software locally installed

PrintPDFToDevice

PDFToPCL

Ghostscript + ImageMagick using convert command

CreatePDF

 

%Zen.Report

GetAllEncompassingPDF

CreatePDF + MergePDFS if they exist

Ghostscript during the merge

ABNPRINTNEW

PrintPDFToDevice (PCL)

Ghostscript + ImageMagick using convert command

PrintABNToScreen

ConvertPDFToText

Ghostscript

PRINTPDF

PDFToPCL

create txt file and then pdf to get embedded barcode

 

PDFTOPCL

Ghostscript + ImageMagick using convert command

 

PrintPDFToDevice

Ghostscript + ImageMagick using convert command

 

ConvertPDFToText if wanting to print to screen

GhostScript

PRINTPDFS

PDFToPCL

Ghostscript + ImageMagick using convert command

 

Does anyone have experience with Intersystems Reports and if so, can you give me some insights as to the functionality as a replacement for Ghostscript and ImageMagick for above functionality?

Thank you in advance for any help on this.

2 Comments
Discussion (2)2
Log in or sign up to continue
Question
· Feb 11

VS CODE Search Options

Hi All,

In my DB, it has more than 10,000 files. I tried to search for a particular file (mac), but there is no search option to find it. Can you help me find that option to search for a file?

2 Comments
Discussion (2)2
Log in or sign up to continue
Article
· Feb 11 3m read

Uma visão sobre Dynamic SQL e Embededd SQL

 

 

Ao contrário do filme, citado através da imagem (para quem não conhece, Matrix, 1999), a escolha entre Dynamic SQL e Embededd SQL, não é uma escolha entre a verdade e a fantasia, mas, mesmo assim é uma decisão a ser tomada. Abaixo, tentarei facilitar a escolha de vocês.

Caso sua necessidade seja interações entre o cliente e a aplicação (consequentemente o banco de dados), o Dynamic SQL pode ser mais apropriado, pois “molda-se” muito facilmente com estas alterações de consultas. Entretanto, este dinamismo tem um custo, a cada consulta nova, ela é remodelada, podendo ter um custo maior para a execução. Abaixo um exemplo simples de um trecho de código Python.

Exemplo de SQL Dynamic

Apenas com base na informação acima, o Embededd SQL é a melhor escolha? Depende. Pensando única e exclusivamente em agilidade na execução, poderíamos partir para esta escolha. Uma vez que as instruções SQL são inseridas diretamente no código de programação, utilizando-se de variáveis HOST para entrada e saída de dados. O objetivo também não é ensinar como utilizar uma ou outra opção, e sim abrir a mente para possibilidade, conhecendo um pouco sobre cada um.

Abaixo, temos algumas características relevantes e que devem ser levadas em consideração quando iniciar um desenvolvimento que exija uma consulta SQL:

 Como já mencionado, o Embededd SQL é várias lembrado pelo seu desempenho, mas, isto não é uma corrida e nem só de velocidade se vive. Sua integração com diversas linguagens de alto nível, fazem com que os desenvolvedores possam utilizar os recursos de melhor forma, isto dá-se devido ao fato de não precisarem de tantas buscas em arquivos externos ou scripts separados, tornando o código mais limpo e sustentável.

É notado também pela sua consistência, afinal, alterações no banco de dados podem ser espelhadas no código SQL, evitando assim possíveis inconsistências nos dados. E por final, porém não menos importante, o fato das consultas estarem dentro do código, torna-o mais seguro, pois podem ser implementados controles de acesso diretamente no aplicativo, evitando assim acessos não autorizados e consultas indevidas.

Bom, agora podemos ver o que sustenta o Dynamic SQL. Este dinamismo é facilmente notado em sua flexibilidade, isto é, tudo é moldado enquanto está acontecendo, consultas, condições e até nomes de tabelas ou campos, beneficiando assim o cliente, o usuário. É marcado também pela facilidade de administração, uma vez que os DBAs conseguem realizar manutenções nos dados e bancos, conferindo em tempo real o impacto causado, evitando assim maiores problemas de compilação.

O resumo de toda esta informação, com mais teoria e pouca “prática” é que não há um lado certo ou um lado errado, até mesmo um vilão ou um mocinho, o fato é que o conhecimento sobre o que será desenvolvido, uma análise profunda das necessidades, levará a uma escolha...

De qual lado da força você estará?

2 Comments
Discussion (2)3
Log in or sign up to continue
Article
· Feb 11 2m read

A look at Dynamic SQL and Embedded SQL

   

 

 

Unlike the movie mentioned in the image (for those who don't know, Matrix, 1999), the choice between Dynamic SQL and Embedded SQL is not a choice between truth and fantasy, but it is still a decision to be made. Below, I will try to make your choice easier. 

If your need is interactions between the client and the application (and consequently the database), Dynamic SQL may be more appropriate, as it "adapts" very easily to these query changes. However, this dynamism has a cost: with each new query, it is remodeled, which can have a higher cost to execute. Below is a simple example of a Python code snippet. 

Example of Dynamic SQL 

Based solely on the information above, is Embedded SQL the best choice? It depends. Thinking solely and exclusively about agility in execution, we could go for this choice. Since the SQL instructions are inserted directly into the programming code, using HOST variables for data input and output. The goal is not to teach how to use one or another option, but rather to open your mind to the possibilities, learning a little about each one. 

Below, we have some relevant features that should be taken into consideration when starting a development that requires an SQL query: 

As already mentioned, Embedded SQL is often remembered for its performance, but this is not a race and speed is not the only thing we live for. Its integration with several high-level languages ​​allows developers to use the resources in a better way, this is due to the fact that they do not need to search as many external files or separate scripts, making the code cleaner and more maintainable. 

It is also noted for its consistency, after all, changes to the database can be mirrored in the SQL code, thus avoiding possible inconsistencies in the data. And last but not least, the fact that the queries are within the code makes it more secure, since access controls can be implemented directly in the application, thus avoiding unauthorized access and inappropriate queries. 

Well, now we can see what supports Dynamic SQL. This dynamism is easily noticed in its flexibility, that is, everything is shaped as it happens, queries, conditions and even table or field names, thus benefiting the client, the user. It is also marked by ease of administration, since DBAs can perform maintenance on data and databases, checking the impact caused in real time, thus avoiding major compilation problems. 

The summary of all this information, with more theory and little “practice” is that there is no right or wrong side, not even a villain or a good guy, the fact is that knowledge about what will be developed, an in-depth analysis of needs, will lead to a choice... 

Which side of the force will you be on?

 
 
16 Comments
Discussion (16)6
Log in or sign up to continue