#API REST

0 Seguidores · 113 Publicaciones

La transferencia de estado representacional (REST) es un estilo de arquitectura de software que define un conjunto de restricciones que se utilizarán para crear servicios web. Los servicios web que se ajustan al estilo arquitectónico REST, denominados servicios web RESTful (RWS), proporcionan interoperabilidad entre sistemas informáticos en Internet. Los servicios web RESTful permiten que los sistemas solicitantes accedan y manipulen representaciones textuales de recursos web mediante el uso de un conjunto uniforme y predefinido de operaciones sin estado. Otros tipos de servicios web, como los servicios web SOAP, exponen sus propios conjuntos arbitrarios de operaciones.

Artículo Ricardo Paiva · nov 10, 2025 3m read

Seguramente queríais usar la especificación OpenAPI (OAS) en formato JSON que utilizasteis para vuestra clase spec en el paquete iris-web-swagger-ui de IRIS.
La OAS generada por el método ##class(%REST.API).GetWebRESTApplication(...) es muy básica, sin descripciones de los parámetros ni de la estructura esperada de las respuestas.

Así que, después de crear vuestra aplicación REST a partir de una OAS, deberíais tener:

0
0 7
Artículo Luis Angel Pérez Ramos · oct 31, 2025 6m read

¡Sí sí! ¡Adelante! No os habéis equivocado, estáis en vuestra querida Comunidad de Desarrolladores de InterSystems en español.

Os preguntaréis a qué viene el título de este artículo, pues muy sencillo, hoy estamos aquí reunidos para honrar al Inquisidor y elogiar la gran labor desempeñada por el mismo. 

Y bien, ¿quién o qué es el Inquisidor?

1
0 27
Artículo Kurro Lopez · oct 23, 2025 1m read

Hola a todos,

Este es un rápido consejo de como usar URL en servicios RES API sin distinción de mayúsculas y minúsculas.

Si tienes una clase que extiende de %CSP.REST y Ens.BusinessService, para crear un servicoi REST API, y tienes definido tu WebApplication en minúsculas

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
    <Route Url="/user" Method="POST" Call="User"/>
    <Route Url="/login" Method="POST" Call="Login"/>
</Routes>
}

Solo aceptará URL en minúsculas, por ejemplo: http://myserver/myproduction/user

2
0 25
Artículo Carlos Castro · jun 1, 2025 18m read

Buenas a todos,

en capítulos anteriores, vimos como "Proteger los datos: Se un mejor cerrajero", en el que explicábamos como proteger nuestros recursos aplicando un control extra al acceso mediante OAUTH2 que nos ofrece Intersystems. Y como no hay 2 sin 3, aquí tenemos un tercer articulo, en el cual vamos a explicar como "avisar a la policía" de que alguien malicioso está intentando acceder a nuestros datos.

4
2 92
Artículo Marco Bahamondes · jun 30, 2025 3m read

Introducción

InterSystems IRIS permite crear APIs REST utilizando clases ObjectScript y el framework %CSP.REST. Esta funcionalidad permite desarrollar servicios modernos para exponer datos a aplicaciones web, móviles o integraciones externas.

En este artículo aprenderás cómo crear una API REST básica en InterSystems IRIS, incluyendo:

  • Clase de datos persistente
  • Clase REST con métodos GET y POST
  • Web application para exponer la API
  • Demostración completa con Docker

Paso 1: Crear la clase de datos Demo.Producto

0
0 71
Artículo Alessandra Carena · jun 6, 2025 6m read

​En el artículo anterior, Generación de Especificaciones OpenAPI, vimos qué es OpenAPI, por qué es útil para documentar los servicios REST y cómo generar un archivo de especificación en formato .yaml o .json. También exploramos cómo IRIS permite crear automáticamente esta documentación a partir del código existente, siguiendo el enfoque code-first.

0
4 84
Artículo Alberto Fuentes · mayo 27, 2025 3m read

Hola desarrolladores:

Al observar la avalancha de herramientas de desarrollo impulsadas por IA y al estilo vibe coding que han estado apareciendo últimamente casi cada mes, con funciones cada vez más emocionantes, me preguntaba si sería posible aprovecharlas con InterSystems IRIS. Al menos para construir un frontend. Y la respuesta es: ¡sí! Al menos con el enfoque que seguí en este ejemplo.

Aquí tenéis mi receta para crear la interfaz de usuario mediante prompts frente al backend de InterSystems IRIS:

  1. Tened una API REST en el lado de IRIS, que refleje una especificación Open API (swagger).
  2. Generad la interfaz de usuario con cualquier herramienta de vibe coding (por ejemplo, Lovable) y apuntad la interfaz al endpoint de la API REST.
  3. ¡Y listo!

Aquí tenéis el resultado de mi propio experimento: una interfaz 100 % generada por prompts frente a la API REST de IRIS, que permite listar, crear, actualizar y eliminar entradas de una clase persistente (Open Exchange, código del frontend, vídeo).

¿Cómo es la receta en detalle?

0
0 35
Artículo Sanjib Pandey · mar 28, 2025 5m read

Contexto:

Esta guía proporciona una visión general de cómo diseñar e implementar una interfaz API REST para consultar los datos demográficos de un paciente desde un sistema de Registro Electrónico de Pacientes (EPR) utilizando HealthConnect. El proceso implica enviar una solicitud de consulta con el número de identificación del paciente, recuperar la respuesta del sistema EPR, extraer los datos demográficos requeridos del mensaje HL7 y enviarlos como una respuesta JSON al proveedor. El diagrama del proceso de alto nivel se muestra a continuación (Captura de pantalla 1).

0
0 47
Artículo Alessandra Carena · feb 11, 2025 7m read

Introducción

Una API REST (Representational State Transfer) es una interfaz que permite que diferentes aplicaciones se comuniquen entre sí a través del protocolo HTTP, utilizando operaciones estándar como GET, POST, PUT y DELETE. Las API REST son ampliamente utilizadas en el desarrollo de software para exponer servicios accesibles por otras aplicaciones, permitiendo la integración entre diferentes sistemas.

Sin embargo, para garantizar que las API sean fáciles de comprender y utilizar, es fundamental contar con una buena documentación. Aquí es donde entra en juego OpenAPI.

2
0 149
Artículo Joel Espinoza · feb 4, 2025 2m read

Estimada comunidad,

Quería comentarles que hoy publique en OpenExchange un acelerador de APIs muy simple de implementar (con algún parecido a Redis, pero más funcional) y con resultados bastante buenos, a continuación está la publicación del README, espero les sea de ayuda!

https://openexchange.intersystems.com/package/memoria

Memoria

Esta aplicación permite almacenar el resultado de una llamada a la API GET de forma permanente o por un periodo de tiempo, reduciendo los tiempos de respuesta al cliente final.

En el ejemplo a continuación se utiliza la API pública de Rick & Morty para realizar varias consultas al servidor. Cada consulta por sí sola y utilizando la conexión a internet del hogar demora alrededor de 300 ms. Al utilizar el acelerador el tiempo de respuesta es de alrededor de 7 ms.

Cliente

La clase memoria.client es la encargada de llamar al método MGet, este método ejecuta la llamada a la API externa pero primero valida si la información de esta API está cacheada en la tabla memoria.store, de ser así valida que esté dentro del Time to Live (TTL) configurado y retorna el dato, si el TTL ya expiró borra la información y genera la llamada, almacena el resultado y lo retorna al programa.

Código de prueba

Para una API estática, es decir, lista de países, nombre de ciudades, etc., recomiendo usar TTL=0 para mantener la lista en la tienda.

Resultado de la API

En la primera llamada (cuadrado rojo en la parte superior), el tiempo de la llamada fue de 722 ms y en todas las demás llamadas, el tiempo fue de aproximadamente 7 ms, en este caso solo un 1 % del tiempo original.

Después de 10 segundos (valor TTL), el tiempo aumentó a 220 ms

Resultado

Panel

El Panel es una pequeña aplicación que le permite administrar los datos almacenados en caché y eliminarlos si es necesario.

Vista del panel

1
0 61
Artículo Alberto Fuentes · jul 16, 2024 4m read

wsgi_logo

Contexto

La Interfaz de Pasarela de Servidor Web (WSGI, por sus siglas en inglés) es una convención de llamada para que los servidores web puedan reenviar solicitudes a aplicaciones o frameworks web escritos en el lenguaje de programación Python. WSGI es un estándar de Python descrito en detalle en PEP 3333.

🤔 Ok, gran definición, ¿y qué tiene que ver con IRIS?

IRIS 2024.2+ tiene una nueva característica que os permite ejecutar aplicaciones WSGI directamente en IRIS. Esta característica es una excelente manera de integrar IRIS con otros frameworks y bibliotecas de Python.

Esto sigue la tendencia de la experiencia Python primero, donde podéis usar Python para interactuar con IRIS, y ahora también podéis ejecutar aplicaciones Python directamente en IRIS.

Cómo usarla

Para instanciar una aplicación WSGI en IRIS, necesitáis configurarla en la sección Seguridad->Aplicaciones->Aplicaciones Web del Portal de Gestión de IRIS.

Ejemplo simple de Flask:

Archivo llamado app.py en el directorio /irisdev/app/community:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

Configuración de la Interfaz de Usuario

image

En esta sección, podéis configurar la aplicación WSGI introduciendo lo siguiente:

  • Nombre de Aplicación

  • esto corresponde al nombre del archivo de la aplicación WSGI.

  • Ejemplo: app.py pero sin la extensión .py: app.

  • Nombre de la función a llamar

    • la función invocable que será llamada por el servidor WSGI

    • por ejemplo, app corresponde a la variable app en el archivo app.py

      • app = Flask(__name__)
  • Directorio de aplicaciones WSGI

    • la ruta donde se encuentra la aplicación WSGI
    • ej: /irisdev/app/community
  • Tipo de protocolo Python

    • puede ser wsgi o asgi
      • wsgi es el valor por defecto y el utilizado en este ejemplo
      • asgi es para aplicaciones asíncronas
        • por ahora soportamos asgi de forma sincronizada con el adaptador a2wsgi
  • DEBUG

    • si está marcada, la aplicación WSGI se ejecutará en modo depuración
      • esto es útil para fines de desarrollo, ya que cualquier cambio en la aplicación WSGI se recargará automáticamente

Fusión fichero CPF

También podéis configurar la aplicación WSGI utilizando el fichero de configuración CPF de IRIS. He aquí un ejemplo de configuración:

[Actions]
CreateApplication:Name=/flask,NameSpace=IRISAPP,WSGIAppLocation=/irisdev/app/community/,WSGIAppName=app,WSGICallable=app,Type=2,DispatchClass=%SYS.Python.WSGI,MatchRoles=:%ALL,WSGIDebug=0,WSGIType=0

Archivos de registro

Los registros de la aplicación (logs) WSGI se almacenan en el archivo WSGI.log ubicado en el directorio mgr de la instancia.

Ejemplos

Aquí tenéis algunos ejemplos de aplicaciones WSGI que podéis ejecutar en IRIS, pretenden mostrar cómo ejecutar diferentes frameworks de Python en IRIS.

Básicamente, el caso de uso será el mismo para todos los frameworks:

Endpoints

  • /iris - Devuelve un objeto JSON con las 10 principales clases presentes en el espacio de nombres IRISAPP.
  • /interop - Un endpoint que hará de "ping" para probar el framework de interoperabilidad de IRIS.
  • /posts - Un endpoint CRUD sencillo para un objeto Post.
  • /comments - Un endpoint CRUD sencillo para un objeto Comment.

Modelo de objeto

Objeto Post:

  • id
  • title
  • content

Objeto Comment:

  • id
  • post_id (foreign key to Post)
  • content

Flask

Django

FastAPI

Limitaciones

  • El ASGI es soportado sincrónicamente por ahora con el adaptador a2wsgi.
  • Las aplicaciones tornado ( jupyter, streamlit, .. ) no están soportadas ya que no son compatibles con WSGI.
2
0 346
Artículo Jose-Tomas Salvador · ene 22, 2025 1m read

En vuestra Producción de Interoperabilidad, siempre podíais tener una Business Operation (BO) que fuera un cliente HTTP y que utilizara OAuth 2.0 para la autenticación. Sin embargo, teníais que personalizar la BO para esta metodología de autenticación. Desde la versión 2024.3, que se lanzó recientemente, hay una nueva capacidad que proporciona nuevos ajustes para gestionar esto de forma más sencilla.

0
0 56
Artículo Ricardo Paiva · ene 8, 2025 4m read

Link de Git: https://github.com/ecelg/InterSystems-IRIS-as-a-Spotify-REST-client

Recientemente se me ocurrió una idea: ¿cómo puedo poner mi lista de reproducción en IRIS? 🧐

Al mismo tiempo, me dijeron que debía pagar mi suscripción de Spotify 💸💸... oooh... ¿y si obtengo algunos datos de la API de Spotify? Así que empecé a investigar sobre eso.

Como en la mayoría de los desarrollos, comencemos con la documentación de la API: https://developer.spotify.com/documentation/web-api

Para obtener los datos, se requiere solicitar un token de acceso en la URL del endpoint de token. 🧐

0
0 89
Artículo Rolano Rebelo · dic 5, 2024 4m read

🌍 Inclusión e Innovación en la Educación 🌍
Nuestro proyecto reimagina el aprendizaje para todos los estudiantes, con un enfoque en la accesibilidad y experiencias interactivas. Diseñado con el objetivo de hacer que la educación sea atractiva e inclusiva, esta herramienta está creada para apoyar a estudiantes de todas las habilidades en el aprendizaje de material complejo de forma intuitiva.

💡 Lo que hace
Esta aplicación educativa transforma presentaciones de lecciones en sesiones de estudio interactivas:

0
0 62
Artículo Andrii Mishchenko · oct 16, 2024 5m read

En este artículo, nos adentraremos en el funcionamiento de una aplicación publicada en OpenExchange llamada db-management-tool que sirve como herramienta de gestión de bases de datos, explorando la arquitectura y las tecnologías que la sustentan. Comprenderemos cómo funciona la aplicación para daros una visión de su diseño, cómo gestiona bases de datos, tablas y cómo la API interactúa con los datos.

0
0 62
Artículo Jose-Tomas Salvador · sep 30, 2024 3m read

Existen muchas aplicaciones para trabajar con mensajes HL7 V2, pero las herramientas para trabajar con XML en el Portal de Gestión o los IDE de IRIS son limitadas. Aunque hay muchas utilidades externas e IDEs que funcionan con mensajes XML e incluso documentos C-CDA, hay una razón convincente para poder hacer pruebas directamente en el marco de trabajo C-CDA de IRIS.

Hacer pruebas dentro del entorno de IRIS os proporciona el contexto necesario:

0
0 78
Artículo Ricardo Paiva · jun 28, 2024 9m read

Integrar aplicaciones frontend de React con servicios backend como la base de datos IRIS a través de APIs REST puede ser una forma poderosa de construir aplicaciones web robustas. Sin embargo, un obstáculo común que los desarrolladores suelen encontrar es el problema de Cross-Origin Resource Sharing (CORS), que puede impedir que el frontend acceda a los recursos en el backend debido a restricciones de seguridad impuestas por los navegadores web. En este artículo, exploraremos cómo abordar los problemas de CORS al integrar aplicaciones web de React con servicios backend de IRIS.

Creando el esquema

Comenzamos definiendo un esquema simple llamado Pacientes:

Class Prototype.DB.Patients Extends %Persistent [ DdlAllowed ]
{

Property Name As %String;

Property Title As %String;

Property Gender As %String;

Property DOB As %String;

Property Ethnicity As %String;
}

Podéis insertar algunos datos de prueba en la tabla para propósitos de testeo. Personalmente, encuentro Mockaroo útil cuando se trata de crear datos falsos. Permite descargar los datos de prueba como un archivo .csv que se puede importar directamente en el Portal de Gestión.

Definición de servicios REST

Luego, definimos algunos servicios REST.

Class Prototype.DB.RESTServices Extends %CSP.REST
{

Parameter CONTENTTYPE = "application/json";
    
XData UrlMap [ XMLNamespace = "http://www/intersystems.com/urlmap" ]
{
<Routes>
    <Route Url = "/patients" Method="Get" Call="GetPatients"/>
    <Route Url = "/patient/:id" Method="Post" Call="UpdatePatientName"/>
</Routes>
}

ClassMethod GetPatients() As %Status
{
    #Dim tStatus As %Status = $$$OK

    #Dim tSQL As %String = "SELECT * FROM Prototype_DB.Patients ORDER BY Name"

    #Dim tStatement As %SQL.Statement = ##class(%SQL.Statement).%New()
    
    Set tStatus = tStatement.%Prepare(tSQL)

    If ($$$ISERR(tStatus)) Return ..ReportHttpStatusCode(..#HTTP400BADREQUEST, tStatus)

    #Dim tResultSet As %SQL.StatementResult

    Set tResultSet = tStatement.%Execute()

    #Dim tPatients As %DynamicArray = []

    While (tResultSet.%Next()) {
        #Dim tPatient As %DynamicObject = {}
        Set tPatient.ID = tResultSet.ID
        Set tPatient.Name = tResultSet.Name
        Set tPatient.Title = tResultSet.Title
        Set tPatient.Gender = tResultSet.Gender
        Set tPatient.DOB = tResultSet.DOB
        Set tPatient.OrderedBy = tResultSet.OrderedBy
        Set tPatient.DateOfOrder = tResultSet.DateOfOrder
        Set tPatient.DateOfReport = tResultSet.DateOfReport
        Set tPatient.Ethnicity = tResultSet.Ethnicity
        Set tPatient.HN = tResultSet.HN
        Do tPatients.%Push(tPatient)
    }
    Do ##class(%JSON.Formatter).%New().Format(tPatients)
    Quit $$$OK
}

ClassMethod UpdatePatientName(pID As %Integer)
{
    #Dim tStatus As %Status = $$$OK
    #Dim tPatient As Prototype.DB.Patients = ##class(Prototype.DB.Patients).%OpenId(pID,, .tStatus)
    If ($$$ISERR(tStatus)) Return ..ReportHttpStatusCode(..#HTTP404NOTFOUND, tStatus)
    #Dim tJSONIn As %DynamicObject = ##class(%DynamicObject).%FromJSON(%request.Content)
    Set tPatient.Name = tJSONIn.Name
    Set tStatus = tPatient.%Save()
    If ($$$ISERR(tStatus)) Return ..ReportHttpStatusCode(..#HTTP400BADREQUEST, tStatus)
    #Dim tJSONOut As %DynamicObject = {}
    Set tJSONOut.message = "patient name updated successfully"
    Set tJSONOut.patient = ##class(%DynamicObject).%New()
    Set tJSONOut.patient.ID = $NUMBER(tPatient.%Id())
    Set tJSONOut.patient.Name = tPatient.Name
    Do ##class(%JSON.Formatter).%New().Format(tJSONOut)
    Quit $$$OK
}

}

Luego, procedemos a registrar la aplicación web en el portal de gestión.

  1. En el Portal de Gestión, navegad a: System Administration -> Security -> Application -> Web Application -> Create New Web Application.
  2. Rellenad el formulario como se muestra a continuación. image
  3. Las APIs definidas en Prototype/DB/RESTServices.cls estarán disponibles en http://localhost:52773/api/prototype/*
  4. Ahora podemos verificar que las APIs están disponibles solicitando los endpoints usando Postman. image

Creando el frontend

He utilizado Next.js para crear un frontend simple. Next.js es un popular framework de React que permite a los desarrolladores construir aplicaciones React renderizadas del lado del servidor (SSR) con facilidad.

Mi frontend es una tabla sencilla que muestra los datos de pacientes almacenados en IRIS y ofrece la funcionalidad para actualizar los nombres de los pacientes.

 const getPatientData = async () => {
    const username = '_system'
    const password = 'sys'
    try {
        const response: IPatient[] = await (await fetch("http://localhost:52773/api/prototype/patients", {
        method: "GET",
        headers: {
          "Authorization": 'Basic ' + base64.encode(username + ":" + password),
          "Content-Type": "application/json"
        },
      })).json()
      setPatientList(response);
    } catch (error) {
      console.log(error)
    }
  }

Parece que tenemos todo listo, pero si ejecutamos npm run dev directamente, obtenemos un error de CORS :(

Resolviendo CORS

Un error de CORS ocurre cuando una aplicación web intenta hacer una solicitud a un recurso en un dominio diferente, y la política de CORS del servidor restringe el acceso desde el origen del cliente, lo que resulta en que la solicitud sea bloqueada por el navegador. Podemos resolver el problema de CORS ya sea en el frontend o en el backend.

Establecer encabezados de respuesta (el enfoque de backend)

Primero, añadimos el parámetro HandleCorsRequest a la misma clase dispatcher Prototype/DB/RESTServices.cls donde definimos los endpoints de la API.

Parameter HandleCorsRequest = 1;

Luego, definimos el método OnPreDispatch dentro de vuestra clase dispatcher para establecer los headers de respuesta.

   ClassMethod OnPreDispatch() As %Status
    {
        Do %response.SetHeader("Access-Control-Allow-Credentials","true")
        Do %response.SetHeader("Access-Control-Allow-Methods","GET, PUT, POST, DELETE, OPTIONS")
        Do %response.SetHeader("Access-Control-Max-Age","10000")
        Do %response.SetHeader("Access-Control-Allow-Headers","Content-Type, Authorization, Accept-Language, X-Requested-With")
        quit $$$OK
    } 

Uso del proxy Next.js (el enfoque frontend)

En vuestro archivo next.config.mjs, añadid la función de reescritura (rewrite) de la siguiente manera:

 /** @type {import('next').NextConfig} */
        const nextConfig = {
            async rewrites() {
                return [
                    {
                        source: '/prototype/:path',
                        destination: 'http://localhost:52773/api/prototype/:path'
                    }
                ]
            }
        };

        export default nextConfig;

Y actualizad cualquier URL de fetch desde http://127.0.0.1:52773/api/prototype/:path a /prototype/:path.

El Producto Final

A continuación dejo el código para la página frontend:

'use client'
import { NextPage } from "next"
import { useEffect, useState } from "react"
import { Table, Input, Button, Modal } from "antd";
import { EditOutlined } from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import base64 from 'base-64';
import fetch from 'isomorphic-fetch'
const HomePage: NextPage = () => {
  const [patientList, setPatientList] = useState<IPatient[]>([]);
  const [isUpdateName, setIsUpdateName] = useState<boolean>(false);
  const [patientToUpdate, setPatientToUpdate] = useState<IPatient>()
  const [newName, setNewName] = useState<string>('')
  const getPatientData = async () => {
    const username = '_system'
    const password = 'sys'
    try {
        const response: IPatient[] = await (await fetch("http://localhost:52773/api/prototype/patients", {
        method: "GET",
        headers: {
          "Authorization": 'Basic ' + base64.encode(username + ":" + password),
          "Content-Type": "application/json"
        },
      })).json()
      setPatientList(response);
    } catch (error) {
      console.log(error)
    }
  }

  const updatePatientName = async () => {
     let headers = new Headers()
    const username = '_system'
    const password = 'sys'
    const ID = patientToUpdate?.ID
    try {
      headers.set("Authorization", "Basic " + base64.encode(username + ":" + password))
      const response: { message: string, patient: { ID: number, Name: string } } =
        await (await fetch(`http://127.0.0.1:52773/api/prototype/patient/${ID}`, {
        method: "POST",
          headers: headers,
          body: JSON.stringify({Name: newName})
      })).json()
      let patientIndex = patientList.findIndex((patient) => patient.ID == response.patient.ID)
      const newPatientList = patientList.slice()
      newPatientList[patientIndex] = {...patientList[patientIndex], Name: response.patient.Name}
      setPatientList(newPatientList);
      setPatientToUpdate(undefined);
      setNewName('')
      setIsUpdateName(false)
    } catch (error) {
      console.log(error)
    }
  }
  const columns: ColumnsType = [
    {
      title: 'ID',
      dataIndex: 'ID',
    },
    {
      title: "Title",
      dataIndex: "Title"
    },
    {
       title: 'Name',
      dataIndex: 'Name',
      render: (value, record, index) => {
        return (
          <div className="flex gap-3">
            <span>{value}</span>
            <span className="cursor-pointer" onClick={() => {
              setIsUpdateName(true)
              setPatientToUpdate(record)
            }}><EditOutlined /></span>
          </div>
        )
      }
    },
    {
      title: "Gender",
      dataIndex: 'Gender'
    },
    {
      title: "DOB",
      dataIndex: "DOB"
    },
    {
      title: "Ethnicity",
      dataIndex: "Ethnicity"
    },
    {
      title: 'HN',
      dataIndex: "HN"
    }
  ]

  useEffect(() => {
    getPatientData();
  }, [])
  return (
    <>
      <div className="min-h-screen">
        <Modal open={isUpdateName} footer={null} onCancel={() => {
          setIsUpdateName(false);
          setPatientToUpdate(undefined);
          setNewName('')
        }}>
          <div className="flex flex-col gap-5 pb-5">
            <div>
              <div className="text-2xl font-bold">Update name for patient {patientToUpdate?.ID} </div>
            </div>
            <div className="text-xl">Original Name: { patientToUpdate?.Name}</div>
            <div className="flex flex-row gap-2">
              <Input className="w-60" value={newName} onChange={(event) => setNewName(event.target.value)} />
              <Button type="primary" onClick={updatePatientName}>OK</Button>
              <Button onClick={() => {
                setIsUpdateName(false)
                setPatientToUpdate(undefined);
                setNewName('')
              }}>Cancel</Button>
            </div>
          </div>
        </Modal>
      <div className="flex justify-center py-10">
        <div className="h-full w-4/5">
          {patientList.length > 0 && <Table dataSource={patientList} columns={columns}/>}
        </div>
        </div>
      </div>
    </>
  )
}

export default HomePage

Ahora, cuando visitéis http://localhost:3000, esto es lo que veréis: image

Repositorio de Github para el proyecto: https://github.com/xili44/iris-react-integration

Me gustaría agradecer a Bryan (@Bryan Hoon), Julian(@Julian Petrescu) y Martyn (@Martyn Lee), de la oficina de Singapur, por su apoyo y experiencia.

0
0 241
Artículo Jose-Tomas Salvador · jun 3, 2024 1m read

Añadid una credencial para iniciar sesión en la interfaz REST de FHIR - en este caso considerad sólo una autenticación básica

 

Añadid Registro de Servicios - en este caso considerad sólo una autenticación básica

- Configurad un servicio HTTP

- Introducid la ruta al servidor FHIR

- Introducid la URL del servicio FHIR

- Usad la credencial añadida previamente 

 

Añadid una "HS.FHIRServer.Interop.HTTPOperation"

Elegid el Nombre del Servicio

Probad el cliente FHIR

Rastread/seguid el resultado de la prueba

0
1 121
Artículo Alberto Fuentes · mayo 20, 2024 4m read

La especificación OpenAPI (OAS) define una interfaz estándar e independiente del lenguaje para las API HTTP que permite tanto a humanos como a ordenadores descubrir y comprender las capacidades del servicio sin acceso al código fuente, la documentación o mediante la inspección del tráfico de red. Cuando se define correctamente, un consumidor puede entender e interactuar con el servicio remoto con una cantidad mínima de lógica de implementación. Aunque para las API basadas en SOAP existe un asistente especial en InterSystems IRIS que reduce el tiempo de desarrollo de las orquestaciones, no todas las API utilizadas en las integraciones son SOAP. Por eso @Jaime Lerga sugirió añadir un asistente similar al de SOAP para generar un cliente REST a partir de la especificación OpenAPI. La implementación de esta idea reduce el tiempo de desarrollo de las orquestaciones REST API con InterSystems IRIS. Esta idea es una de las más populares en las ideas de InterSystems. Este artículo, el tercero de la serie "Ideas implementadas", se centra en la solución OpenAPI Suite desarrollada por @Lorenzo.Scalese.
 

0
0 122
Artículo Yone Moreno · mayo 17, 2024 52m read

🙂 Buenos días comunidad.

Me gustaría compartir con ustedes, en este artículo, una manera muy práctica, de obtener información relevante de todos los Namespaces de un Entorno. ¿Para qué?. Pues por ejemplo para uno de los casos de uso que más nos encontramos los desarrolladores con respecto a Healtshare: el desafío de necesitar crear 1 servicio, y la odisea de ir entorno a entorno, namespace a namespace, buscando si el puerto XYZAB está libre o no... 🙃

0
0 123
Pregunta Kurro Lopez · mar 15, 2024

Hola a todos,

Por un requerimiento del cliente, tenermos un BS Rest Api con un montón de métodos, necesitamos obtener la IP del invocador, el método y cual es el tiempo que la API ha tomado para procesar.

He encontrado el evento onPreDispatch donde puedo capturar la IP, ClassMethod, etc.. Estoy usando una variable global para guardar esta información.

2
0 182
Artículo Ricardo Paiva · mar 15, 2024 5m read

En este artículo, compartiré el tema que presentamos @Rochael Ribeiro y yo en la Convención Anual (Global Summit) 2023, en la sala "Tech Exchange".

En esa ocasión hablamos de los siguientes temas:

  • Herramientas de Open Exchange para Fast APIs (APIs rápidas)
  • Especificación OpenAPI
  • Desarrollo tradicional vs. Fast API
  • APIs Compuestas (Interoperabilidad)
  • Enfoque Spec-First o Api-First 
  • Gobernanza y Monitorización de APIs
  • Demo (vídeo)

Herramientas de Open Exchange para Fast APIs

Como estamos hablando de desarrollo rápido de APIs modernas (Rest / json) utilizaremos dos herramientas de Open Exchange:

La primera es un framework para el desarrollo rápido de APIs, que explicaremos en este artículo.

https://openexchange.intersystems.com/package/IRIS-apiPub

La segunda es utilizar Swagger como interfaz de usuario para la especificación y documentación de las APIs Rest desarrolladas en la plataforma IRIS, así como su uso/ejecución. La base de su funcionamiento es la especificación OpenAPI (OAS) estándar, que se describe a continuación:

 https://openexchange.intersystems.com/package/iris-web-swagger-ui

 

¿Qué es la especificación OpenAPI (OAS)?

Es un estándar utilizado en todo el mundo para definir, documentar y consumir APIs. En la mayoría de los casos, las APIs se diseñan incluso antes de su implementación. Hablaré más de ello en los próximos apartados.

Es importante porque define y documenta las APIs Rest para su uso, tanto en el lado del proveedor como del consumidor. Pero este patrón también sirve para agilizar las pruebas y las llamadas a las API en las herramientas (Clientes de las APIs Rest) del mercado, como Swagger, Postman, Insomnia, etc…

 

Forma tradicional de publicar APIs utilizando IRIS

Imaginemos que tenemos que crear y publicar una API Rest a partir de un método IRIS existente (imagen inferior).

De la forma tradicional:

1: Tenemos que pensar cómo la llamarán los consumidores. Por ejemplo: Qué ruta y verbo se utilizará y cómo será la respuesta. Ya sea en un objeto JSON o como texto plano.

2: Crear un nuevo método en una clase %CSP.REST que administrará la solicitud http para llamarlo.

3: Gestionar la respuesta del método a la respuesta http prevista para el usuario final.

4: Pensar cómo vamos a proporcionar el código de respuesta y cómo vamos a gestionar las excepciones.

5: Mapear la ruta para nuestro nuevo método.

6: Proporcionar la documentación de la API al usuario final. Probablemente crearemos el contenido OAS manualmente.

7: Y si, por ejemplo, tenemos una carga útil (objeto) de solicitud o respuesta, el tiempo de implementación aumentará, porque también debe documentarse en OAS.

 

¿Cómo podemos ser más rápidos?

Simplemente etiquetando el método IRIS con el atributo [WebMethod]. Sea lo que sea, el framework se encargará de su publicación, utilizando el estándar OAS 3.x.

¿Por qué es tan importante el estándar OAS 3.x? 

Porque también documenta detalladamente todas las propiedades de las cargas útiles de entrada y salida.

De esta forma, cualquier herramienta Rest Client del mercado puede acoplarse instantáneamente a las API, como Insomnia, Postman, Swagger, etc. y ofrecer un contenido de muestra para llamarlas fácilmente.

Usando Swagger ya visualizaremos nuestra API (imagen superior) y la llamaremos. Esto también es muy útil para realizar pruebas.

Personalización de la API

Pero, ¿y si necesito personalizar mi API?

Por ejemplo: En vez del nombre del método, quiero que la ruta sea otra cosa. Y quiero que los parámetros de entrada estén en la ruta, no como un parámetro de consulta.

Definimos una notación específica en la parte superior del método, donde podemos complementar la metainformación que el propio método no proporciona.

En este ejemplo estamos definiendo otra ruta para nuestra API y complementando la información para que el usuario final tenga una experiencia más amigable.

Mapa de proyección para APIs Rest

Este framework soporta numerosos tipos de parámetros.

En este mapa podemos destacar los tipos complejos (los objetos). Se expondrán automáticamente como una carga útil JSON y cada propiedad estará debidamente documentada (OAS) para el usuario final .

 

Interoperabilidad (APIs compuestas)

Al admitir tipos complejos, también se pueden exponer servicios de interoperabilidad.

Es un escenario favorable para crear APIs compuestas, que utilizan la orquestación de múltiples componentes externos (salidas).

Esto significa que los objetos o mensajes utilizados como solicitud o respuesta serán publicados y leídos automáticamente por herramientas como swagger.

Y es una forma excelente de probar componentes de interoperabilidad, porque normalmente ya se sube una plantilla de carga útil para que el usuario sepa qué propiedades utiliza la API.

En primer lugar, el desarrollador puede centrarse en las pruebas y, a continuación, dar forma a la API mediante la personalización.

Enfoque Spec-first o Api-first

Otro concepto muy utilizado hoy en día es tener la API definida incluso antes de su implementación.

Con este framework es posible importar una especificación OpenAPI. Crea la estructura de los métodos (especificación) automáticamente, y faltaría sólo su implementación.

Gobernanza y monitorización de APIs

Para la gobernanza de las APIs, también se recomienda utilizar conjuntamente IAM.

Además de disponer de múltiples plugins, IAM puede acoplarse rápidamente a las APIs a través del estándar OAS.

apiPub ofrece trazabilidad adicional para las APIs (ver el video demostración)

Demostración

<iframe allowfullscreen="" frameborder="0" height="432" scrolling="no" src="https://www.youtube.com/embed/IdJ1PqmhH3c" width="768"></iframe>

Descarga y documentación

Intersystems Open Exchange: https://openexchange.intersystems.com/?search=apiPub

Documentación completa: https://github.com/devecchijr/apiPub

0
0 228
Artículo Luis Angel Pérez Ramos · jun 16, 2023 10m read

Una de las necesidades más comunes por parte de nuestros clientes es la de la creación de servicios REST que permitan acceder a la información presente en IRIS / HealthConnect. La ventaja de estos servicios REST es que permite el desarrollo de interfaces de usuario personalizadas con las tecnologías más actuales aprovechando la fiabilidad y el rendimiento de IRIS en el back-end.

4
2 538
Pregunta Laura Blázquez García · mar 1, 2024

Estoy utilizando RestForms2 para disponer de una API Rest sobre unas tablas de forma rápida.

El caso es que he añadido un trigger a las tablas para que, cada vez que se inserte/actualice/borre un registro, registre en una tabla de históricos los cambios, pudiendo ver el valor original y el nuevo de cada propiedad.

Pero el trigger solamente salta si la inserción se realiza mediante SQL. No salta creando un nuevo objeto.

2
0 185
Artículo Luis Angel Pérez Ramos · feb 26, 2024 5m read

He estado desarrollando una aplicación web que utiliza IRIS como back-end. Trabajé en ella con acceso no autenticado. Estoy llegando al punto en el que me gustaría implementarla para los usuarios, pero primero necesito añadir la autenticación. En vez de utilizar la contraseña para la autenticación predeterminada de IRIS (con contraseña), me gustaría que los usuarios iniciaran sesión con el Inicio de Sesión Único (SSO) de mi organización, o con algún otro proveedor de identidad popular como Google o GitHub. He leído que OpenID Connect es un estándar de autenticación común, y que es admitido por IRIS. ¿Cuál es la forma más sencilla de ponerlo en marcha?

Ejemplo 1: una aplicación CSP simple

La documentación muestra una opción bastante sencilla para utilizar una aplicación CSP como cliente de OpenID Connect.

Los pasos para ello son los siguientes:

  1. Configurar el servidor OAuth 2.0 y el cliente en IRIS. Consultad la sección "Configuración de Caché" del estupendo artículo de Daniel Kutac para obtener más información.

  2. Copie la rutina OAUTH2.ZAUTHENTICATE del repositorio de ejemplos en GitHub en el Namespace %SYS y renombrarlo como ZAUTHENTICATE.

  3. Habilitar la autenticación delegada en todo el sistema.

  4. Crear una página de inicio de sesión personalizada que se extienda desde %OAuth2.Login, y anule el método DefineParameters para especificar el nombre de la aplicación OAuth 2.0 y los ámbitos:

Class MyOAuth2.Login Extends %OAuth2.Login
{

ClassMethod DefineParameters(Output application As %String, Output scope As %String, Output responseMode As %String)
{
    Set application="my application name"
    Set scope="openid profile email"
    Set responseMode=..#RESPONSEMODE
    Quit
}

}
  1. Habilitar la aplicación web para la autenticación delegada y establecer la página de inicio de sesión personalizada en MyOAuth2.Login.cls.

  2. Un truco final: Para que la página de inicio de sesión personalizada funcione, el usuario CSPSystem en IRIS necesita que se le conceda específicamente acceso de LECTURA (READ) a la base de datos en la que vive MyOAuth2.Login.cls.

En ese momento, el inicio de sesión debería "simplemente funcionar": visitar una página CSP en esa aplicación web redirigirá a la página de inicio de sesión en el proveedor de identidad. Después de iniciar sesión, el usuario tendrá una sesión CSP autenticada. Su $username será igual a su identificador de sujeto de SSO/Google/GitHub/donde sea, así que puedo utilizar la autorización incorporada de IRIS para determinar a qué cosas dar acceso.

Ejemplo 2: el problema con REST

¿Qué ocurre si la aplicación web utiliza un controlador REST? El proceso anterior no funciona. Si una aplicación web está habilitada para REST, no hay forma de definir una página de inicio de sesión personalizada. He descubierto que se necesitan algunos pasos más para solucionar este problema.

  1. Crear una aplicación web independiente que no tenga REST habilitado. La ruta de esa aplicación debe comenzar con la ruta de la aplicación REST. Por ejemplo, si la aplicación REST se llama "/csp/api", podríamos llamar a esta nueva aplicación "/csp/api/login". Hay que habilitar la autenticación delegada y establecer la página de inicio de sesión personalizada en la página MyOAuth2.Login.cls.

  2. Establecer la Ruta de la Cookie de Sesión en esta nueva aplicación como la misma que la de la aplicación REST: por ejemplo, "/csp/api". Esto permitirá que ambas aplicaciones compartan una sesión CSP.

  3. Añadir una página CSP a esta nueva aplicación que actuará como "página de inicio". Un usuario deberá acceder primero a esta página para establecer su sesión. Este es un ejemplo que redirige a un endpoint en la API REST tras el inicio de sesión:

Class App.Home Extends %CSP.Page
{

ClassMethod OnPage() As %Status [ ServerOnly = 1 ]
{
    &html<;>
    return $$$OK
}

}
  1. Asegurarsese de que la clase del controlador REST tiene el parámetro UseSession anulado a true.
Class API.REST Extends %CSP.REST
{

Parameter UseSession As BOOLEAN = 1;

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{

}

ClassMethod Test() As %Status
{
    write { "username": ($username) }.%ToJSON()
    return $$$OK
}

}

En este punto, el inicio de sesión en la aplicación REST también "simplemente funcionará". El usuario visitará la página de inicio, será redirigido al inicio de sesión SSO y, finalmente, volverá a la aplicación REST, donde tendrá una sesión CSP autenticada. Hasta donde yo sé, ésta es la forma más sencilla de añadir OpenID Connect a una aplicación IRIS REST.

Otra opción es utilizar la muestra "REST.ZAUTHENTICATE" del repositorio de muestras de seguridad. Esto espera que el front-end adjunte un token de portador OAuth 2.0 a cada solicitud. Sin embargo, no hay una forma definida para que el front-end obtenga este token de acceso. Habrá que implementar ese flujo OAuth en JavaScript (o usar una librería como angular-oauth2-oidc.) También hay que asegurarse de que la aplicación JavaScript y el back-end de IRIS coinciden en todos los elementos de la configuración como el endpoint emisor del servidor de autorización, el id de cliente OAuth 2.0, etc. He descubierto que esto no es una tarea sencilla.

Tengo curiosidad por saber si alguien más utiliza OpenID Connect para autenticar una aplicación IRIS. ¿Existe una forma aún más sencilla? ¿O merece la pena utilizar el enfoque más complicado con tokens de portador? Podéis comentarlo más abajo.

0
0 290
Pregunta Kurro Lopez · feb 12, 2024

Hola a todos,

Como sabéis, es muy complicado depurar una API Rest de Business Service porque el objeto se crea cuando las aplicaciones reciben una solicitud, por lo que no podemos tener el JobId que podemos usar para depurar.

https://docs.intersystems.com/iris20211/csp/docbook/DocBook.UI.Page.cls…

Entonces, estoy tratando de obtener el JobId cuando se crea la clase, escribir una traza en el método OnInit() y escribir el JobId en es traza.

Method OnInit() As%Status
{
	$$$LOGINFO("JobId: "_$JOB)
	hang20breakQuit..OnInit()
}
2
0 249
Artículo Luis Angel Pérez Ramos · dic 5, 2023 3m read

¡Bienvenidos a todos! 

En este breve artículo quería presentar un ejemplo de uso que seguramente a muchos de los que trabajéis con IRIS como backend de vuestras aplicaciones web os hayáis encontrado en más de una ocasión y sería el de la necesidad de enviar desde el frontend un archivo a vuestro servidor.

0
1 234
Artículo Ricardo Paiva · nov 2, 2023 2m read

Preguntas Frecuentes de InterSystems

El significado de cada valor de tiempo de espera es el siguiente.

1. [Tiempo de espera de respuesta del servidor]

Si el procesamiento de IRIS/Caché (ejecución de rutina o consulta) no finaliza dentro de este tiempo establecido, el navegador devolverá un error.

Por ejemplo, si este valor es 60 segundos y se necesitan 90 segundos para ejecutar una rutina/método/consulta, se producirá un error.

0
0 117