# data[].attributes.body
FastAPI es un web framework moderno y rápido (de alto rendimiento) para construir APIs con Python 3.6+ basado en las anotaciones de tipos estándar de Python.

Sus características principales son:

Rapidez: Alto rendimiento, a la par con NodeJS y Go (gracias a Starlette y Pydantic). Uno de los frameworks de Python más rápidos.

Rápido de programar: Incrementa la velocidad de desarrollo entre 200% y 300%.

Menos errores: Reduce los errores humanos (de programador) aproximadamente un 40%.

Intuitivo: Gran soporte en los editores con auto completado en todas partes. Gasta menos tiempo debugging.

Fácil: Está diseñado para ser fácil de usar y aprender. Gastando menos tiempo leyendo documentación.

Corto: Minimiza la duplicación de código. Múltiples funcionalidades con cada declaración de parámetros. Menos errores.

Robusto: Crea código listo para producción con documentación automática interactiva.

Basado en estándares: Basado y totalmente compatible con los estándares abiertos para APIs: OpenAPI (conocido previamente como Swagger) y JSON Schema.

# data[].attributes.body
Pip es un sistema de gestión de paquetes utilizado para instalar y administrar paquetes de software escritos en Python. Muchos paquetes pueden ser encontrados en el Python Package Index (PyPI). Python 2.7.9 y posteriores (en la serie Python2), Python 3.4 y posteriores incluyen pip (pip3 para Python3) por defecto.

pip es un acrónimo recursivo que se puede interpretar como Pip Instalador de Paquetes o Pip Instalador de Python.

Nota: la diferencia es que con npm, es que npm install instala de forma predeterminada los paquetes localmente en un proyecto, mientras que pip install de forma predeterminada los instala globalmente.

Interfaz línea de comando

Una ventaja importante de pip es la facilidad de su interfaz de línea de comandos, el cual permite instalar paquetes de software de Python fácilmente desde solo una orden:

- pip install nombre-paquete

Los usuarios también pueden fácilmente desinstalar algún paquete:

- pip uninstall nombre-paquete

Otra característica particular de pip es que permite gestionar listas de paquetes y sus números de versión correspondientes a través de un archivo de requisitos. Esto nos permite una recreación eficaz de un conjunto de paquetes en un entorno separado (p. ej. otro ordenador) o entorno virtual. Esto se puede conseguir con un archivo correctamente formateado requisitos.txt y la siguiente orden:

- pip install -r requisitos.txt

Con pip es posible instalar un paquete para una versión concreta de Python, sólo es necesario reemplazar ${versión} por la versión de Python que queramos: 2, 3, 3.4, etc:

- pip${versión} install nombre-paquete

# data[].attributes.body
¿Qué es un entorno virtual de python?

Según Python, un entorno virtual es un entorno de Python parcialmente aislado que permite instalar paquetes para que los use una aplicación en particular, en lugar de instalarlos en todo el sistema.

¿Por qué usar entornos virtuales en python?

Si es la primera vez que escuchas sobre un entorno virtual, puedes darte una idea de cómo funciona de la siguiente manera: supongamos que tenemos un computador en donde se le ha instalado python y además tenemos instaladas librerías como OpenCV, numpy, entre otros… solo por dar un pequeño ejemplo.

Y es entonces que hemos incursionado en algunos proyectos, en los cuales vamos a trabajar con las mismas librerías, pero con versiones diferentes.

Entonces, ¿qué hacemos?, instalar cierta versión de la librería, probar el código de uno de los proyectos, desinstalar dicha librería y ahora instalarla, ¿pero con otra versión para probar el código de un segundo proyecto?

¡Esto sería mucho trabajo y nos podría llegar a desesperar!

Y es en ese preciso momento que llegan los entornos virtuales de python a nuestra salvación.

Estos nos permitirán crear entornos de python con sus paquetes estándar, permitiendo instalar los paquetes que necesitemos en cada uno de ellos sin que estos interfieran con otros entornos creados, ni con los paquetes ya instalados en todo el sistema. Es decir que estos nos ayudarán a organizar los paquetes que usamos para nuestros proyectos, y de tal modo trabajaremos eficientemente.

¿Cómo instalar virtualenv?

En esta ocasión vamos a usar virtualenv para la creación de los entornos virtuales. Este no es un módulo estándar (no viene incluido en python) por lo que necesitaremos instalarlo, para ello vamos a usar pip. Entonces nos dirigimos al símbolo del sistema en windows y digitamos:

pip install virtualenv

Esperaremos a que se realice la instalación. Por cierto, si quieres obtener más información sobre virtualenv.

Una vez instalado este módulo, podremos crear los entornos virtuales, instalar paquetes en ellos, ejecutar scripts, entre otros. Esto lo veremos a continuación.

¿Cómo crear un entorno virtual?

Lo primero que tenemos que hacer antes de crear el entorno virtual es ubicarnos en directorio donde queramos que se cree dicho entorno. Ya que estamos en el símbolo del sistema, usaremos el comando cd, que nos permitirá movernos al path deseado.

Una vez que estemos ubicados en dicho path, vamos a digitar:

- virtualenv nombre_del_entorno_virtual

Es decir que para crear el entorno virtual necesitaremos de virtualenv, seguido del nombre que le queramos dar.

Una vez que se presione enter, se creará el entorno virtual. En el símbolo del sistema tendremos un mensaje indicándonos que este se ha creado exitosamente. Mientras que en el directorio donde lo hemos creado, tendremos una nueva carpeta con el nombre del entorno virtual, y dentro podremos encontrar varias carpetas y archivos.

En la número 1, me estoy dirigiendo al directorio en donde deseo crear el entorno virtual, por ello uso el comando cd, para realizar el cambio de directorio. En mi caso voy a crear mi entorno virtual en la carpeta Proyecto1, que está en el escritorio.

Una vez allí voy a proceder con la creación del entorno virtual, para ello he digitado virtualenv p1, que quiere decir que crearemos un entorno virtual llamado p1.

Al dar enter, después de unos segundos nos aparecerá un mensaje el cual indica que el entorno ha sido creado exitosamente.

¿Cómo activar un entorno virtual?

Para activar un entorno virtual, como en pasos anteriores, mediante el símbolo del sistema nos ubicamos en el directorio donde está la carpeta del entorno virtual. Una vez allí digitamos:

-          .\nombre_del_entorno_virtual\Scripts\activate

Como en nuestro ejemplo ya estábamos ubicados en el directorio del entorno virtual, digitaremos esa línea:

En la figura 2 podemos ver que ya estamos ubicados en el directorio donde anteriormente creamos el entorno virtual, por lo que procedemos a activarlo. Para ello hemos digitamos .\p1\Scripts\activate, hemos especificado p1 ya que este es el nombre del entorno creado.

¿Cómo sabemos que ya se ha activado el entorno virtual?

Para saber si se ha activado el entorno virtual, debemos fijarnos en la sección izquierda de la siguiente línea luego de haber ingresado la línea de activación, si en esta aparece entre paréntesis el nombre del entorno virtual, quiere decir que ya está activo.

Esto lo podemos apreciar en la figura2, allí podemos ver que se ha activado el entorno y además lo tenemos rodeado de una circunferencia blanca.

¿Cómo instalar paquetes o módulos en el entorno virtual?

Una vez que tenemos activado el entorno virtual, podremos instalar los paquetes o módulos que necesitemos. Esto lo haremos con pip, como si los instaláramos directamente en el sistema, no cambia en nada. La única diferencia es que solo se instalarán en el entorno virtual, ya que este está activo.

Podemos instalar por ejemplo OpenCV, imutils, para ello digitaremos (recuerda que podrías instalar cualquier otro paquete):

- pip install opencv-contrib-python

Una vez que se realice la instalación, podemos instalar también imutils (u otro paquete que necesitemos).

- pip install imutils

Y de igual manera tendremos que esperar a que se realice la instalación.

¿Cómo correr un programa usando entornos virtuales en python?

Al igual que en los aspectos anteriores, lo que necesitamos es que el entorno esté activo, entonces podremos ejecutar cualquier archivo de python que use las librerías que habíamos instalado.

Por ejemplo, supongamos que tenemos el siguiente script llamado redim.py. Este programa tiene como objetivo leer una imagen y visualizarla junto con su redimensionada.

Además, este se encuentra dentro de una carpeta que está ubicada en el mismo directorio que el entorno virtual. Aunque recuerda que no es necesario que los programas a ejecutar estén en la misma dirección que el entorno virtual.

El programa es el siguiente:

import cv2

import imutils

image = cv2.imread('image_02.jpg')

# Escalando una imagen usando imutils.resize

imageOut = imutils.resize(image,width=300)

cv2.imshow('Imagen de entrada',image)

cv2.imshow('Imagen de salida',imageOut)

cv2.waitKey(0)

cv2.destroyAllWindows()

Ahora, me ubicaré en el directorio donde está presente este programa y lo ejecutaré.

Como puedes apreciar, el proceso para ejecutar un programa desde el símbolo del sistema con un entorno virtual es igual a que si lo hiciéramos directamente sobre el sistema operativo.

¿Como desactivar un entorno virtual de Python?

Para desactivar el entorno virtual de python necesitaremos de:

- deactivate

Si empleamos este en el ejemplo que hemos desarrollado hasta ahora, tendríamos lo siguiente:

Y finalmente como vemos en la figura 7, hemos digitado deactivate, por lo tanto al dar enter, podemos darnos cuenta que (p1) ha desaparecido, y por lo tanto ya no estamos empleando dicho entorno.

# data[].attributes.body
El archivo requirements.txt permite automatizar la instalación de paquetes generalmente, cuando se está desarrollando algún tipo de software (aplicaciones web, videojuegos), es muy común utilizar un conjunto de paquetes o librerías que ayuden a construirlo con un nivel de calidad aceptable en menos tiempo.

Los paquetes necesarios se pueden descargar directamente desde el sitio web; clonar desde un repositorio, por lo general un repositorio Git alojado en Github; o instalarlos directamente usando pip. Sin embargo, este procedimiento manual es muy tedioso y lejos de ser eficiente.

Si por alguna razón se pierden los paquetes obtenidos o se necesita utilizar una nueva computadora para continuar con el desarrollo del proyecto, es necesario volver a los sitios web o repositorios y descargarlos de nuevo, uno por uno.

El archivo requirements.txt permite automatizar la instalación de paquetes Python y por lo tanto agilizar esta parte del proceso de desarrollo de software.

Cómo utilizar el archivo requirements.txt

Hay dos cosas que se deben saber antes de utilizar el archivo requirements.txt. En primer lugar, se debe saber el nombre exacto de los paquetes o librerías que se quieren instalar. El nombre se puede buscar en el repositorio PyPi ejecutando el siguiente comando en una terminal:

$ pip search <package>

Es necesario tener instalado pip para poder ejecutar el comando anterior.

Por ejemplo, si se va a desarrollar un videojuego y para esto necesitamos instalar Pygame, realizamos una búsqueda con pip ejecutando el comando:

$ pip search pygame

El resultado del comando arroja un listado de paquetes:

KezMenu - A simple and basical Pygame library for...

spw - Simple Pygame Wrapper provides a 2D...

Pygame - Pygame gives multimedia to python.

glyph - Pygame typesetting library

zanthor - Zanthor is a game where you play an evil...

En el listado se puede ver la línea que comienza con Pygame, este es el nombre que se debe anotar en el archivo requirements.txt.

Además del nombre del paquete, es recomendable saber también la versión. Al anotar la versión en el archivo requirements.txt, pip instalará esa versión específica a pesar que existan versiones más recientes.

Esto, sin lugar a dudas, evitará que se presenten problemas en el proyecto si el paquete es actualizado a una nueva versión y algunas de sus características son removidas o actualizadas.

Si no se anota el número de versión del paquete, pip instalará por defecto la última versión disponible en el repositorio PyPi.

Para saber la versión, se puede consultar el sitio web del repositorio PyPi o ir al sitio web de cada paquete y revisar las versiones disponibles.

Ahora sí, con estos dos datos se pueden anotar los paquetes Python en el archivo requirements.txt de la siguiente forma:

# Para instalar una versión específica

package==version

# Para instalar una versión igual o superior

package>=version

# Para instalar la versión más reciente

package

Por ejemplo, si se quiere instalar la versión 1.7.1 de Pygame, se anota lo siguiente:

Pygame==1.7.1

Si se desea instalar una versión mayor que o igual a la 1.7.1, se anota lo siguiente:

Pygame>=1.7.1

# data[].attributes.body
pip freeze

Si deseamos saber que paquetes son los que hemos instalado vía pip en nuestro entorno virtual (y no solo allí, ya que este comando también lo podemos usar en el sistema directamente), vamos a digitar:

pip freeze

Este comando a más de indicarnos los paquetes ya instalados, también nos muestra la versión de cada uno de ellos.

Podemos usar este comando en el ejemplo que veníamos haciendo:

Como puedes ver en la figura 4, una vez ingresado pip freeze, y al dar enter, podremos ver los paquetes instalados.

Tal vez te asombre que no solo tengamos imutils y opencv, sino también numpy, esto es debido a que al instalar opencv también se instala numpy.

# data[].attributes.body
Un paquete es una carpeta que contiene varios módulos. Siguiendo el ejemplo anterior, podemos diseñar un paquete matemático creando una carpeta con la siguiente estructura.

matematica/

|-- __init__.py

|-- aritmetica.py

|-- geometria.py

Debe contener siempre un archivo __init__.py (por el momento vacío) para que Python entienda que se trata de un paquete y no de una simple carpeta. Así, podemos acceder a alguno de los módulos del paquete de la siguiente manera.

import matematica.aritmetica

print(matematica.aritmetica.sumar(7, 5))

O bien de la siguiente.

from matematica import aritmetica

print(aritmetica.sumar(7, 5))

También, esta otra:

from matematica.aritmetica import sumar

print(sumar(7, 5))

Python incluye una inmensa cantidad de módulos y paquetes en su instalación (aún más grande es aquella desarrollada por la comunidad, de la que hablaremos más adelante), a los que se conoce como librería estándar. Ahora que sabemos cómo trabajar con ellos, sopesemos esta cuestión.

# data[].attributes.body
FastAPI no se limita a las API. Se puede usar para casi todo lo que hace un marco web, desde entregar páginas web con el motor de plantillas Jinja2 hasta servir aplicaciones basadas en WebSockets.

FastAPI le permite validar el tipo de datos del desarrollador, incluso cuando utiliza consultas JSON anidadas.

Ofrece la función de autocompletar, que le permite crear aplicaciones en menos tiempo y requiere menos esfuerzo.

Es compatible con el vocabulario OpenAPI y JSON Schema, lo que le permite validar y anotar documentos JSON.

FastAPI le permite construir rápidamente una API GraphQL usando un Biblioteca de Python llamado grafeno-pitón.

FastAPI es compatible con OAuth 2.0 y con proveedores externos.

# data[].attributes.body
Uvicorn es una implementación de servidor web ASGI para Python.

Hasta hace poco, Python carecía de una interfaz mínima de servidor / aplicación de bajo nivel para marcos asimétricos. los Especificación ASGI llena este vacío y significa que ahora podemos comience a construir un conjunto común de herramientas utilizables en todos los marcos asíncronos.

Uvicorn actualmente es compatible con HTTP / 1.1 y WebSockets.

# data[].attributes.body
https://fastapi.tiangolo.com/es/tutorial/

# data[].attributes.body
¿Qué es un ORM?

Un ORM (de sus siglas en inglés, Object Relational Mapper), no es más que una utilidad o librería que permite manipular las tablas de una base de datos como si fueran objetos de nuestro programa.
Lo más habitual es que una tabla se corresponda con una clase, cada fila de una tabla con un objeto (o instancia de una clase), las columnas de una tabla con los atributos de una clase y las claves ajenas (o Foreign Keys) con relaciones entre clases (definidas también a partir de atributos).

Ventajas de usar un ORM

Las principales ventajas de usar un ORM son:

Acceder a las tablas y filas de una base de datos como clases y objetos.

En la mayoría de ocasiones no es necesario usar el lenguaje SQL. El ORM se encarga de hacer las traducciones oportunas.

Independencia de la base de datos. Es posible cambiar de motor de base de datos modificando muy poco código en la aplicación.

Incrementa la productividad del desarrollador.

# data[].attributes.body
Un modelo en Django es un tipo especial de objeto que se guarda en la base de datos. Una base de datos es una colección de datos. Es un lugar en el cual almacenarás la información sobre usuarios, tus entradas de blog, etc. Utilizaremos una base de datos SQLite para almacenar nuestros datos. Este es el adaptador de base de datos predeterminado en Django -- será suficiente para nosotros por ahora.

Puedes pensar el modelo en la base de datos, como una hoja de cálculo con columnas (campos) y filas (datos).

# data[].attributes.headline
¿Qué es y cómo usar pip install sqlalchemy?

# data[].attributes.subject
¿Qué es y cómo usar pip install sqlalchemy?

# data[].attributes.body
¿Cómo funciona SQLALchemy?

SQLAlchemy proporciona una interfaz única para comunicarte con los diferentes drivers de bases de datos Python que implementan el estándar Python DBAPI.

Este estándar, especifica cómo las librerías Python que se integran con las bases de datos deben exponer sus interfaces. Por tanto, al usar SQLAlchemy no interactuarás directamente con dicho API, sino con la interfaz que precisamente proporciona SQLAlchemy. Esto es lo que permite cambiar el motor de base de datos de una aplicación sin modificar apenas el código que interactúa con los datos.

En definitiva, al usar SQLAlchemy es necesario instalar también un driver que implemente la interfaz DBAPI para la base de datos que vayas a utilizar.

Ejemplos de estos drivers son:

psycopg para PostgreSQL

mysql-connector para MySQL

cx_Oracle para Oracle

La librería SQLAlchemy es el kit de herramientas SQL de Python y el mapeador relacional de objetos.

SQLAlchemy es el kit de herramientas SQL de Python y el Mapeador relacional de objetos que ofrece a los desarrolladores de aplicaciones la máxima potencia y flexibilidad de SQL. Esta proporciona un conjunto completo de patrones de persistencia conocidos a nivel empresarial, diseñados para un acceso a bases de datos eficiente y de alto rendimiento, adaptados a un lenguaje de dominio simple y Pythonic.

# data[].attributes.body
Pydantic es una librería que nos permite crear dataclasses en Python. Una dataclass (en el contexto de Python) es una clase donde el constructor (y otros métodos especiales) son "autogenerados", de forma que lo único que tenemos que especificar son los atributos que va a tener dicha clase. Python dispone de la librería estándar "dataclasses", que nos proporciona un decorador para poder crear este tipo de clases.
Por su parte, Pydantic ofrece una serie de prestaciones de las que carecen las dataclasses propias de Python. Las dos principales características, que además van a resultarnos especialmente útiles a la hora de gestionar configuraciones, son:

1. Auto-conversión de tipos. Por defecto, Pydantic intentará convertir el valor asignado a un atributo al de su tipo. Así, si un atributo de tipo entero lo inicializásemos con un texto "123", Pydantic intentará realizar la conversión de dicho string al entero 123.
2. Validación de tipos. Cada atributo de la clase tiene asignado un tipo (utilizando el tipado estándar de Python). Si el valor asignado a un atributo no es válido, la inicialización de la clase fallará (por ejemplo, intentar inicializar un campo numeral con un texto "123abc").
Antes de comenzar, es importante destacar que este artículo se basa en la versión 1.9 de Pydantic, pero está previsto que a finales de 2022 se publique la versión 2, donde cambiarán (y mejorarán) bastantes aspectos.

# data[].attributes.body
Una de las características del lenguaje Python es que el tipado que usa es dinámico, es decir, permite que una variable pueda cambiar su tipo durante la ejecución de un programa. La razón es que los tipos dependen del valor que tenga asignado dicha variable en un momento dado, no de una propiedad de la variable en sí.

# data[].attributes.body
La manera más fácil de explicar cómo funciona HTTP es describiendo cómo se abre una página web:

1. En la barra de direcciones del navegador, el usuario teclea example.com.

2. El navegador envía esa solicitud, es decir, la petición HTTP, al servidor web que administre el dominio example.com. Normalmente, la solicitud del cliente dice algo así como “Envíame este archivo”, pero también puede ser simplemente “¿Tienes este archivo?”.

3. El servidor web recibe la solicitud HTTP, busca el archivo en cuestión (en nuestro ejemplo, la página de inicio de example.com, que corresponde al archivo index.html) y envía en primer lugar una cabecera o header. Esta cabecera le comunica al cliente, mediante un código de estado, el resultado de la búsqueda. Para conocer más detalles acerca de los códigos de estado, no te pierdas nuestro artículo al respecto.

4. Si se ha encontrado el archivo solicitado y el cliente ha solicitado recibirlo (y no solo saber si existe), el servidor envía, tras el header, el message bodyo cuerpo del mensaje, es decir, el contenido solicitado: en nuestro ejemplo, el archivo index.html.

5. El navegador recibe el archivo y lo abre en forma de página web.

¿Para qué se usa HTTP?

Cuando se creó, el protocolo HTTP solo servía para solicitar documentos HTML a un servidor web. Hoy en día, en cambio, se usa con gran variedad de fines:

Los navegadores usan HTTP para solicitar cualquier tipo de archivo habitual en las webs modernas: de texto, de vídeo, de código de programación, etc.

Los programas de aplicación utilizan HTTP para cargar archivos y actualizaciones de servidores lejanos.

La API basada en REST es una solución que utiliza HTTP para controlar servicios web.

Otra tecnología que se basa en HTTP es WebDAV.

En la comunicación de máquina a máquina se utiliza HTTP como protocolo de comunicación entre servicios web.

Los reproductores multimedia también utilizan HTTP.

Las operaciones de acceso a bases de datos en

# data[].attributes.body
Utilice el método GET para recuperar recursos de objeto de negocio y recursos de estructura de objeto.

Sintaxis

GET uri?parámetro=valor&parámetro=valor&...

uri es un URI. La longitud de la ruta del URI no puede sobrepasar ningún límite especificado por el sistema.

parámetro es un parámetro de consulta.

valor es el valor del parámetro de consulta.

Ejemplo: recuperar un recurso de objeto de negocio

El método siguiente recupera un recurso de objeto de negocio:
GET /maxrest/rest/mbo/asset/123

Se devuelve el XML siguiente:

<?xml version="1.0" encoding="UTF-8" ?>
<ASSET xmlns="http://www.ibm.com/maximo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ASSETNUM>11200</ASSETNUM>
<SERIALNUM>3481-52</SERIALNUM>
<ASSETTAG>3751</ASSETTAG>
<LOCATION>BR200</LOCATION>
<DESCRIPTION>HVAC System- 50 Ton Cool Cap/ 450000 Btu Heat Cap</DESCRIPTION>
< ASSETUID>123</ASSETUID>
.
.
</ASSET>
La respuesta del recurso se muestra en XML. El valor del formato predeterminado puede configurarse en la propiedad del sistema mxe.rest.mbo.defaultformat.

Ejemplo: recuperar un recurso de estructura de objeto
El método siguiente recupera un recurso de estructura de objeto:
GET /maxrest/rest/os/mxasset/123
Se devuelve el XML siguiente:

<?xml version="1.0" encoding="UTF-8" ?>
<QueryMXASSETResponse xmlns="http://www.ibm.com/maximo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
creationDateTime="2011-04-07T11:43:59-04:00"
transLanguage="EN" baseLanguage="EN" messageID="1302195161355515345"
maximoVersion="7 5 20110405-0030 V7500-718" rsStart="0" rsTotal="1"
rsCount="1">
<MXASSETSet>
<ASSET>
<ASSETNUM>11200</ASSETNUM>
<SERIALNUM>3481-52</SERIALNUM>
<ASSETTAG>3751</ASSETTAG>
<LOCATION>BR200</LOCATION>
<DESCRIPTION>HVAC System- 50 Ton Cool Cap/ 450000 Btu Heat Cap</DESCRIPTION>
< ASSETUID>123</ASSETUID>
.
.
<ASSETMETER>
<ACTIVE>1</ACTIVE>
<ASSETMETERID>63</ASSETMETERID>
<LASTREADING>0</LASTREADING>
<METERNAME>PRESSURE</METERNAME>
.
.
</ASSETMETER>
<ASSETSPEC>
<ASSETATTRID>SPEED</ASSETATTRID>
<ASSETSPECID>2138</ASSETSPECID>
.
.
</ASSETSPEC>
<ASSETSPEC>
<ASSETATTRID>SHAFTDIA</ASSETATTRID>
<ASSETSPECID>2139</ASSETSPECID>
.
.
</ASSETSPEC>
</ASSET>
</MXASSETSet>
</QueryMXASSETResponse>

Los datos de recurso de estructura de objeto incluyen datos de activo, de medidor de activo y de especificación de activo basados en la configuración del objeto dentro de la estructura de objeto MXASSET. Todos los campos que están configurados para que se incluyan o excluyan se implementan en los datos.

La ruta del URI puede contener el ID del recurso como forma de seleccionar un recurso específico. En el ejemplo anterior, el ID es 123. El valor del ID es un ID exclusivo para el objeto que está registrado en la tabla MAXATTRIBUTE. Si no se proporciona ningún ID, la respuesta incluye todas las apariciones del recurso, dependiendo de las restricciones de seguridad en el usuario. El ID es el único campo de objeto de negocio que puede formar parte de la ruta del URI para criterios de selección. Los demás campos pueden utilizarse como parámetros de consulta en el URI para filtrado de selección.

Cuando utiliza el recurso de estructura de objeto, los objetos de nivel inferior no pueden tener relaciones. La estructura de objeto da soporte a un gráficos de objetos de negocio relacionados. Las relaciones forman parte de la definición de estructura de objeto.

Puede atravesar los objetos de negocio relacionados para mover de un recurso a otro si existe una relación válida entre el objeto origen y destino.

Parámetros de consulta y operadores
Para captar un recurso del que se conoce su ID exclusivo, puede proporcionar el ID del recurso como parte de la ruta del URI. También puede utilizar parámetros de consulta para filtrar y captar colecciones de recursos.
Parámetro _opmodeor
Utilice el parámetro _opmodeor para evaluar varios campos utilizando una condición OR entre los valores en lugar de la condición predeterminada AND.
Parámetros _rsStart y _maxItems
Los parámetros _rsStart y _maxItems se utilizan juntos para controlar el número de registros devueltos para una solicitud y para permitir la paginación a través de una gran volumen de registros.
Parámetro _orderbyasc
El parámetro _orderbyasc controla el orden de clasificación de los datos devueltos.
Parámetros _includecols y _excludecols
Utilice los parámetros _includecols y _excludecols para controlar el contenido de los atributos que se devuelven en respuesta a una consulta.
Parámetro _dropnulls
Establezca el parámetro _dropnulls en false para incluir campos que tienen un valor nulo en la respuesta de la consulta.
Parámetros _format y _compact
La API de REST soporta las representaciones (formatos) XML y JSON. Puede utilizar el parámetro _format o la negociación de contenido para especificar una representación de recurso. Puede utilizar el parámetro _compact para especificar el formato JSON compacto.
Negociación de contenido de representaciones
La API de REST soporta la identificación del formato de representación utilizando la negociación de contenido como alternativa al uso del parámetro de consulta _format.
Desplazamiento dentro de la sesión
Cuando se desplaza por las páginas de datos, se puede mejorar el rendimiento manteniendo una colección de recursos.
Almacenamiento en memoria caché de solicitudes GET
Habilitando el almacenamiento en memoria caché de las solicitudes GET, puede mejorar los tiempos de repuesta de solicitudes de datos de recursos que el mismo usuario ha sometido anteriormente.

# data[].attributes.body
Utilice el método POST para actualizar o insertar un recurso.

Para actualizar un recurso, debe especificar el ID del recurso. Para crear un recurso, debe especificar la clave primaria y todos los campos necesarios que no tienen un valor predeterminado, pero no es necesario ningún ID.

Para actualizar o insertar un recurso de estructura de objeto, puede especificar el parámetro _action para identificar acciones proporcionadas por la infraestructura de integración, por ejemplo, Change o AddChange.

Para actualizar o insertar un objeto de nivel inferior de un recurso de estructura de objeto, los datos del formulario deben identificar cada aparición del objeto de nivel inferior.

Cuando utilice el método POST para crear un recurso, especifique el parámetro de consulta _ulcr con el valor 1 para que la respuesta incluya un vínculo para que el cliente acceda al nuevo recurso. De lo contrario, el contenido del recurso se incluye en la respuesta. El vínculo se incluye en la propiedad de cabecera Ubicación y el código de respuesta HTTP es 201 para identificar que se proporciona un vínculo en lugar de los datos.

Ejemplo: insertar un activo

El método siguiente inserta el activo 127 dentro de la planta BEDFORD utilizando un recurso de objeto de negocio. El activo y la planta forman la clave primaria.

POST maxrest/rest/mbo/asset HTTP/1.1
assetnum=127&siteid=BEDFORD&description=mi_nueva_descripción&type=OPERATING

Ejemplo: actualizar un activo especificando su ID

El método siguiente actualiza un activo proporcionando el ID como parte del URI:

POST maxrest/rest/mbo/asset/1234 HTTP/1.1
description=mi_nueva_descripción&type=OPERATING

Ejemplo: especificar una acción

El método siguiente utiliza el parámetro _action para especificar una acción Change:

POST maxrest/rest/mbo/asset/968 HTTP/1.1
_action=Change&description=mi_nueva_descripción

Ejemplo: actualizar un registro que tiene varios objetos de nivel inferior

El método siguiente agrega dos líneas de orden de compra a una orden de compra, y cada línea tiene dos costes de orden de compra:

POST maxrest/rest/os/mxpo/1234 HTTP/1.1
description=new_po_desc&
poline.id1.polinenum=1&poline.id1.item=ABC&poline.id1.description=nueva_descripción&
poline.id1.pocost.id1-1.costlinenum=1&poline.id1.pocost.id1-1.gldebitacct=nuew_gl_acct_a&
poline.id1.pocost.id1-2.costlinenum=2&poline.id1.pocost.id1-2.gldebitacct=new_gl_acct_b&
poline.id2.polinenum=2&poline.id2.item=XYZ&poline.id2.description=nueva_descripción&
poline.id2.pocost.id2-1.costlinenum=1&poline.id2.pocost.id2-1.gldebitacct=new_gl_acct_c&
poline.id2.pocost.id2-2.costlinenum=2&poline.id2.pocost.id2-2.gldebitacct=new_gl_acct_d&

En el ejemplo, los identificadores identifican los parámetros siguientes:

Identificador de grupo
Parámetros identificadosid1 | Parámetros que pertenecen a POLINE 1
id1-1 | Parámetros que pertenecen a POCOST 1 para POLINE 1
id1-2 | Parámetros que pertenecen a POCOST 2 para POLINE 1
id2 | Parámetros que pertenecen a POLINE 2
id2-1 | Parámetros que pertenecen a POCOST 1 para POLINE 2
id2-2 | Parámetros que pertenecen a POCOST 2 para POLINE 2

# data[].attributes.body
Utilice el método PUT para actualizar o insertar un recurso. Una solicitud de actualización debe proporcionar el ID exclusivo del recurso. Para actualizar un recurso de estructura de objeto, se requiere el ID del objeto principal.

Para actualizar o insertar un recurso de estructura de objeto, puede especificar el parámetro _action para identificar acciones proporcionadas por la infraestructura de integración, por ejemplo, las acciones Change o AddChange.

Ejemplo: actualizar un activo

El método siguiente actualiza el activo que tiene el ID 1234. La descripción del activo se cambia por mi_nueva_descripción y el tipo se cambia por OPERATING:

PUT maxrest/rest/mbo/asset/1234 HTTP/1.1
description=mi_nueva_descripción&type=OPERATING

Ejemplo: actualizar un objeto de nivel inferior
El método siguiente actualiza el objeto de negocio assetspec, que es un nivel inferior de asset. El valor se cambia por nuevo_valor y la descripción se cambia por mi_nueva_descripción:

PUT maxrest/rest/mbo/assetspec/5678 HTTP/1.1
value=mi_nuevo_valor&description=mi_nueva_descripción

Ejemplo: establecer el contexto de un objeto de nivel superior
Para insertar o actualizar un objeto de negocio de nivel inferior, es posible que tenga que establecer el contexto del objeto de negocio de nivel superior, como en el ejemplo siguiente, en el que se actualiza la descripción de la línea de OC y se proporciona el ID de la OC para el contexto:

PUT maxrest/rest/mbo/po/1234/poline/5678 HTTP/1.1
description=mi_nueva_descripción

# data[].attributes.body
El método HTTP PATCH se utiliza para realizar una actualización parcial de un recurso de OSLC. A diferencia del método PUT, el método PATCH no suprime las propiedades de recurso local que no están incluidas en la petición. El método PATCH se debe especificar utilizando la cabecera x-method-override.

Se aplican las reglas siguientes cuando utiliza el método PATCH para sustituir un recurso de OSLC:

Se actualizan todas las propiedades literales especificadas en el documento de solicitud. Las propiedades literales que no se especifiquen como parte de la solicitud no se ven afectadas de forma explícita por la infraestructura. Sin embargo, pueden verse implícitamente afectadas por la lógica empresarial que está conectada al recurso.

Se actualizan todas las propiedades de recursos locales o se sustituyen por los valores de la propiedad correspondiente de la solicitud. Si la propiedad de recurso no está incluida en la solicitud, el recurso local correspondiente no se ve explícitamente afectado por la infraestructura. Si la propiedad de recurso está incluida, su valor sustituye o actualiza el valor en el servidor.

Los recursos de referencia no pueden actualizarse de forma explícita. No obstante, puede actualizar las propiedades que hagan referencia al recurso, y las propiedades siguen el modelo de actualización de propiedades literales.

La implementación de PATCH tiene dos casos de uso:

Puede sustituir una propiedad de recurso local con el contenido de la petición. Este caso de uso es la implementación predeterminada.

Puede buscar y comparar los elementos de matriz de recurso contenidos en la petición con los elementos existentes en el servidor. Dependiendo de si se ha encontrado una coincidencia de búsqueda, los elementos de matriz de recurso se actualizan o insertan. Un elemento de matriz nunca se suprime de la propiedad de recurso local. Para utilizar este caso de uso, el cliente debe establecer la cabecera de petición HTTP PATCHTYPE en el valor MERGE (se distingue entre mayúsculas y minúsculas).

# data[].attributes.body
El método DELETE requiere el ID exclusivo del recurso.

Para suprimir un recurso de estructura de objeto, se requiere el ID del objeto principal.

Ejemplo: suprimir un activo
El método siguiente suprime el activo 1234:

DELETE maxrest/rest/mbo/asset/1234 HTTP/1.1

# data[].attributes.headline
¿Qué es y cómo usar Infraestructura de una API REST?

# data[].attributes.subject
¿Qué es y cómo usar Infraestructura de una API REST?

# data[].attributes.body
La API de REST forma parte de la infraestructura de integración y maneja las solicitudes de los clientes externos.

El diagrama siguiente proporciona una visión general de cómo la API de REST maneja las solicitudes.

Cuando un consumidor externo inicia una solicitud, un controlador de la API de REST dirige la solicitud de recurso al manejador de recursos adecuado. El manejador de recursos interactúa con los recursos para ejecutar la solicitud. Cuando se completa la solicitud, el serializador de recursos procesa el recurso o la colección de recursos. El serializador de recursos devuelve la representación como respuesta del recurso. Se proporcionan serializadores para XML y JSON.

Puesto que la API de REST está dentro de la infraestructura de integración, la API de REST puede utilizar la autenticación, la autorización y las propiedades del sistema de motor de automatización de procesos.

El controlador de la API de REST es un servlet. El rendimiento y el ajuste de carga y escalabilidad se realiza a nivel de servidor de aplicaciones, de la misma manera que para otros componentes web.

# data[].attributes.headline
¿Qué es y cómo usar Representaciones soportadas JSON, xml?

# data[].attributes.subject
¿Qué es y cómo usar Representaciones soportadas JSON, xml?

# data[].attributes.body
La API de REST soporta XML y JSON como representaciones. Las representaciones están soportadas por la implementación de clases de serializador que están registradas en las propiedades del sistema.

Las representaciones XML y JSON está registradas en las propiedades del sistema API de REST siguientes:

mxe.rest.serializer.mbo.xml

mxe.rest.serializer.os.xml

mxe.rest.serializer.mbo.json

mxe.rest.serializer.os.json

Puede ampliar serializadores para proceso personalizado. Puede crear serializadores para tipos de recurso existentes y para instancias individuales de recursos de objeto de negocio o de estructura de objeto.

Para recursos de estructura de objeto, el formato XML para la API de REST es parecido al formato soportado por la infraestructura de integración.

# data[].attributes.headline
¿Qué es y cómo usar Propiedades de la cabecera HTTP?

# data[].attributes.subject
¿Qué es y cómo usar Propiedades de la cabecera HTTP?

# data[].attributes.body
Los URI para los recursos REST de Rule Execution Server soportan algunos campos de cabecera HTTP y parámetros URI genéricos. Las colecciones de recursos soportan el parámetro count, filtros y servicios de paginación.

Todos los recursos REST soportan los siguientes campos de cabecera HTTP y parámetros de URI. Puede combinar cualquiera de los parámetros URI genéricos o de tipo de colección en un recurso. Por ejemplo, puede combinar el parámetro fecha con servicios de transferencia de páginas para visualizar los conjuntos de reglas resultantes por páginas y con la fecha en el formato iso8601.

Campos de cabecera HTTP

Accept

Especifica los tipos de contenido que son válidos en el mensaje de respuesta. Si el servidor no puede responder con el tipo de contenido solicitado, se devolverá el código de estado HTTP 406 No Aceptable. Puede utilizar el parámetro de URI equivalente, en lugar del campo de cabecera HTTP.

Accept-Language

Envía la lista de idiomas que son válidos para el mensaje de respuesta. Por ejemplo, Accept-Language: fr, pt-BR significa que el idioma preferido es francés, pero que el portugués de Brasil también se acepta. Puede utilizar el parámetro de URI equivalente, en lugar del campo de cabecera HTTP.

Content-Type

Indica qué tipo de contenido del cuerpo de entidad se envía al destinatario.

X-Method-Override

X-HTTP-Method-Override

Indica la operación HTTP que se pasa a través de la solicitud actual. Puede utilizar los parámetros de URI equivalentes, en lugar de los campos de cabecera HTTP.

Parámetros de URI genéricos

En la API REST de Rule Execution Server, los siguientes parámetros son genéricos.

accept

Utilice este parámetro en el mensaje de solicitud para especificar los tipos de contenido que son válidos en el mensaje de respuesta. Este parámetro es equivalente al campo de cabecera HTTP Accept.

accept-language

Utilice este parámetro en el mensaje de solicitud para enviar la lista de idiomas que son válidos para el mensaje de respuesta. Este parámetro es equivalente al campo de cabecera HTTP Accept-Language.

parts

Utilice este parámetro en el mensaje de solicitud para especificar una lista de una o más partes que se van a devolver en el mensaje de respuesta. Utilice una línea vertical |(%7C en la codificación URL) para separar los elementos de la lista. También puede especificar all o none como valor del parámetro parts. El valor predeterminado es all. Por ejemplo, la respuesta a la solicitud siguiente contiene el nombre, el número de versión y las propiedades de los conjuntos de reglas que pertenecen a la RuleApp especificada.

date

Se utiliza en el mensaje de solicitud para especificar el formato de fecha que se espera en el mensaje de respuesta: iso8601 para ISO-8601 o long para el modelo Linux. El valor predeterminado es iso8601.

Parámetros para tipos de colección

Todos los resultados de REST de Rule Execution Server que son colecciones de recursos soportan el parámetro count, filtros y servicios de transferencia de páginas. Puede utilizar la API DOJO para definir servicios de transferencia de páginas.

Estos parámetros sólo son aplicables al método GET, que devuelve colecciones. Utilice los siguientes elementos de sintaxis para compilar la solicitud y respuesta:

Solicitud

URL: /collection

Método: GET

Cabecera: "Range: items=start-stop"

Respuesta

Cabecera: "Content-Range: items start-stop/count"

Cuerpo: el contenido de la colección entre el índice start-stop.

count

Si el valor de este parámetro es true o no se especifica, la respuesta devuelve texto sin formato que contiene el número de elementos en la colección resultante de la vía de acceso del URI de consulta.

nombreCampo

Para proporcionar servicios de filtrado, puede añadir pares clave/valor como parámetros de consulta aplicables a los miembros de la colección. El valor puede ser un nombre estático o una expresión regular. Para utilizar una expresión regular, inicie el valor con exp( y termínelo con un paréntesis de cierre ).

orderby

Este parámetro ordena la lista resultante según el nombre de campo especificado. Puede añadir más de un parámetro orderby. El ejemplo siguiente ordena las RuleApps por nombre y número de versión.

# data[].attributes.headline
¿Qué es y cómo usar Códigos de respuesta?

# data[].attributes.subject
¿Qué es y cómo usar Códigos de respuesta?

# data[].attributes.body
Los códigos de estado de respuesta HTTP indican si se ha completado satisfactoriamente una solicitud HTTP específica. Las respuestas se agrupan en cinco clases:

1. Respuestas informativas (100–199),

2. Respuestas satisfactorias (200–299),

3. Redirecciones (300–399),

4. Errores de los clientes (400–499),

5. y errores de los servidores (500–599).

Los códigos de estado se definen en la sección 10 deRFC 2616. Puedes obtener las especificaciones actualizadas en RFC 7231.

# data[].attributes.body
El Intercambio de Recursos de Origen Cruzado (CORS) es un mecanismo que utiliza cabeceras HTTP adicionales para permitir que un user agent (en-US) obtenga permiso para acceder a recursos seleccionados desde un servidor, en un origen distinto (dominio) al que pertenece. Un agente crea una petición HTTP de origen cruzado cuando solicita un recurso desde un dominio distinto, un protocolo o un puerto diferente al del documento que lo generó.

Un ejemplo de solicitud de origen cruzado: el código JavaScript frontend de una aplicación web que es localizada en http://domain-a.com utiliza XMLHttpRequest para cargar el recurso http://api.domain-b.com/data.json.

Por razones de seguridad, los exploradores restringen las solicitudes HTTP de origen cruzado iniciadas dentro de un script. Por ejemplo, XMLHttpRequest y la API Fetch siguen la política de mismo-origen. Ésto significa que una aplicación que utilice esas APIs XMLHttpRequest sólo puede hacer solicitudes HTTP a su propio dominio, a menos que se utilicen cabeceras CORS.

# data[].attributes.body
“A class should have one, and only one, reason to change.”

La S del acrónimo del que hablamos hoy se refiere a Single Responsibility Principle (SRP). Según este principio “una clase debería tener una, y solo una, razón para cambiar”. Es esto, precisamente, “razón para cambiar”, lo que Robert C. Martin identifica como “responsabilidad”.

El principio de Responsabilidad Única es el más importante y fundamental de SOLID, muy sencillo de explicar, pero el más difícil de seguir en la práctica.

El propio Bob resume cómo hacerlo: “Gather together the things that change for the same reasons. Separate those things that change for different reasons”, es decir: “Reúne las cosas que cambian por las mismas razones. Separa aquellas que cambian por razones diferentes”.

# data[].attributes.body
“You should be able to extend a classes behavior, without modifying it.”

El segundo principio de SOLID lo formuló Bertrand Meyer en 1988 en su libro “Object Oriented Software Construction” y dice: “Deberías ser capaz de extender el comportamiento de una clase, sin modificarla”. En otras palabras: las clases que usas deberían estar abiertas para poder extenderse y cerradas para modificarse.

En su blog Robert C. Martin defendió este principio que a priori puede parecer una paradoja. Es importante tener en cuenta el Open/Closed Principle (OCP) a la hora de desarrollar clases, librerías o frameworks.

# data[].attributes.body
“Derived classes must be substitutable for their base classes.”

La L de SOLID alude al apellido de quien lo creó, Barbara Liskov, y dice que “las clases derivadas deben poder sustituirse por sus clases base”.

Esto significa que los objetos deben poder ser reemplazados por instancias de sus subtipos sin alterar el correcto funcionamiento del sistema o lo que es lo mismo: si en un programa utilizamos cierta clase, deberíamos poder usar cualquiera de sus subclases sin interferir en la funcionalidad del programa.

Según Robert C. Martin incumplir el Liskov Substitution Principle (LSP) implica violar también el principio de Abierto/Cerrado.

# data[].attributes.body
“Make fine grained interfaces that are client specific.”

En el cuarto principio de SOLID, el tío Bob sugiere: “Haz interfaces que sean específicas para un tipo de cliente”, es decir, para una finalidad concreta.

En este sentido, según el Interface Segregation Principle (ISP), es preferible contar con muchas interfaces que definan pocos métodos que tener una interface forzada a implementar muchos métodos a los que no dará uso.

# data[].attributes.body
“Depend on abstractions, not on concretions.”

Llegamos al último principio: “Depende de abstracciones, no de clases concretas”.

Así, Robert C. Martin recomienda:

1. Los módulos de alto nivel no deberían depender de módulos de bajo nivel. Ambos deberían depender de abstracciones.

2. Las abstracciones no deberían depender de los detalles. Los detalles deberían depender de las abstracciones.

El objetivo del Dependency Inversion Principle (DIP) consiste en reducir las dependencias entre los módulos del código, es decir, alcanzar un bajo acoplamiento de las clases.