[[:desarrolladores:webservice_uso|Volver]]
----
===== Creando recursos. =====
La creación de recursos es mediante el método **POST**. La dirección a la que hay que realizar el post es como una **URI ** pero sin el **token**puesto que no lo tendremos. Por ejemplo si deseamos crear una orden para autorizar, la dirección del post sería **URI BASE + ordenes**. En el entorno de testing nos queda:
|https://ws.test.suap.com.ar/procesador/doV2/orden |
Un request mediante **POST**mas un contenido en esa dirección puede terminar en una orden autorizada. En términos generales un **POST**a una dirección de recurso puede instanciar un recurso en suap. Existe la posibilidad de que no ocurra esto ya que puede haber errores o datos incompletos.
|
* **Política de persistencia**. Si la respuesta del **POST** contiene una sección **REST** con una clave **token** y un valor diferente de **null**, entonces el recurso se persistió. Su **URI ** será exactamente la misma del **POST** + el **token.**
==== Contenido (content) del POST ====
En términos formales el contenido del **POST** es un **JSON** con los atributos del recurso que el consumidor desea crear. Dicho JSON está estructurado en dos grandes secciones que representan dos políticas diferentes de como se referencia la información dentro de suap. Una sección es **REST** y la otra sección es **SEARCH. \\ \\ **
| \\ **Contenido de un POST a un recurso ordenes \\ https://ws.test.suap.com.ar/procesador/doV2/orden ** \\ { "REST": {…}, \\ “SEARCH”: {…} \\ } |
=== Sección REST ===
En esta sección se indican los atributos con su valor y los recursos relacionados mediante su **URI. ** Por ejemplo, en una orden, la **fecha de realización ** es un atributo cuyo nombre es “**FechaRealizacion**” que debe contener una fecha en formato: yyyy-mm-dd hh:mm:ss. Un afiliado es un recurso relacionado que debe ser especificado por su **URI**.
Supongamos que deseamos instanciar un recurso orden con:
* Fecha de realización 23/06/2018
* Afiliado Marta Laura Corbalán del ejemplo anterior, cuyo recurso tiene como** URI \\ ** [[https://ws.test.suap.com.ar/procesador/doV2/afiliados/7C9tIPdWMNTt99Zn1afALxroGVuQMt|https://ws.test.suap.com.ar/procesador/doV2/afiliados/7C9tIPdWMNTt99Zn1afALxroGVuQMt]]** \\ \\ **
Para pedirle al WS que cree el recurso orden con esos datos especificados en la sección **REST** debemos armar el siguiente JSON:
|POST a ordenes (testing) \\ https://ws.test.suap.com.ar/procesador/do/V1.0/ordenes \\ { “REST”:{ “FechaRealizacion”:”2018-06-23 00:00:00”, “afiliados”: \\ “https://ws.test.suap.com.ar/procesador/doV2/afiliados/7C9tIPdWMNTt99Zn1afALxroGVuQMt” \\ }, \\ … }} |
En general es poco probable que se cuente con la URI de los recursos y mas que nada al principio. Por lo que si el consumidor fuera por este camino tendría que implementar primero una serie de herramientas para poder buscar afiliados para poder incorporarlos en la sección REST, y lo mismo con los prescriptores y así con todos los recursos relacionados a una orden en este ejemplo. Recién entonces podría armar un contenido completo para realizar el POST y obtener finalmente el recurso instanciado en suap.
Si bien el WS no impide estas prácticas tampoco la alienta. Es por eso que ofrecemos la sección SEARCH que hace exactamente lo ante dicho pero en una cantidad menor de pasos.
=== Sección SEARCH ===
En esta sección se le indica a suap que se van a identificar los recursos mediante busquedas por sus atributos. Es decir, por ejemplo si es el POST a una orden y no tenemos el **token** del afiliado que deseamos, podemos indicar que se lo busque por su nombre, DNI, o cualquier dato parcial o completo que tengamos del mismo. Suap aplicará una política simple en esta condición, si encuentra un único recurso con esos criterios de búsqueda, entonces lo utilizará, si encuentra mas de uno requerirá que sea seleccionado uno por parte del usuario mediante la sección VIEW del response.
Cabe destacar que los atributos deben seguir siendo especificados en la sección **REST**.
A modo de ejemplo un uso de la sección **SEARCH** del WS identificando al afiliado por su DNI y un conjunto de practicas identificados por sus ultimos 4 digitos del NBU.
| \\ POST a un recurso ordenes \\ https://ws.test.suap.com.ar/procesador/doV2/orden \\ { \\ "REST":{ \\ "FechaRealizacion":"2019-03-09", \\ "FechaPrescripcion":"2019-03-02", \\ "DiagnosticoTexto":"Texto diagnostico" \\ }, \\ "SEARCH":{ \\ "afiliado":[ \\ {"DocTipo.igual":"DNI"}, \\ {"DocNumero.igual":"10044895"} \\ ], \\ "prestador":[ \\ {"NombreCompuesto.contenga":"…."} \\ ], \\ "prescriptor":[ \\ {"NombreCompuesto.contenga":"Abenda"} \\ ], \\ "items":[ \\ [{"CodigoConvenio.igual":"660711"} \\ ], \\ [{"CodigoConvenio.igual":"660413"} \\ ]] \\ } \\ } |
**Este ejemplo crea una orden de PAMI, simplemente creando un ejemplo con otro afiliado de otra OS debería generarse otra orden**
**FALTA DOCUMENTAR**
|
==== Interpretación del VIEW ====
\\ \\ El view es una lista de requerimientos y ofertas que hay que hacerle al usuario. Cada requerimiento u oferta indica exactamente donde debe ir el resultado de lo que el usuario responda. \\ Un requerimiento es algo que faltó o que es necesario resolver por parte del usuario. Por ejemplo un requerimiento puede ser definir un profesional ya que con la matrícula brindada hay dos o mas opciones posibles. Los requerimientos están siempre presentes como un error en la sub sección ERROR de la sección STATUS. \\ Una oferta es algo que le puede ser de utilidad al usuario. Por ejemplo un comprobante para imprimir es algo que el usuario puede necesitar o no para terminar un proceso externo a suap y necesario para el colegio. Pero no es algo necesario para instanciar un recurso. \\ Si se realiza un procesador de la sección VIEW practicamente no haría falta nada mas para instanciar recursos en suap (por ejemplo ordenes), mas allá de que sería quizás torpe y se realizarían muchisimas mas llamadas de las necesarias. Comencemos con un ejemplo considerando que operamos en la instalación de **test**.
|POST a un recurso ordenes \\ https://ws.test.suap.com.ar/procesador/doV2/orden \\ { \\ "REST": {}, \\ "SEARCH": { \\ "afiliado": [ \\ { \\ "NombreCompuesto.contenga": "Juan" \\ } \\ ] \\ } \\ } |
Como es esperable es imposible obtener un recurso **ordenes** con ese content. Por lo que el response del WS contendrá un VIEW requiriendo todo lo que haga falta indicado en ERROR de STATUS cada atributo y recurso faltante. Si no está en** {“STATUS”:{“ERROR”:{..}}}** entonces no es algo necesario es una simple oferta.
|Fracción de response \\ "REST": [], \\ "STATUS": { \\ "ERROR": { \\ "FechaRealizacion": { \\ "CODE": 10060, \\ "MESSAGE": "El atributo es requerido" \\ }, - - -"VIEW": { \\ "FechaRealizacion": { \\ "type": "timestamp", \\ "label": "FechaRealizacion", \\ "path": "REST/FechaRealizacion" \\ } , \\ \\ - - - |
Del response tomamos 3 fragmentos mínimos a modo de ejemplo y vemos que:
- **{“REST”:[]…}** Es una lista vacía por lo que **token ** no está definido. Condición de persistencia no se cumple, ya es condición suficiente para procesar el VIEW.
- En** {“STATUS”:{“ERROR”:{..}}} ** se nos indica que FechaRealización es un atributo requerido mediante un código para que tome decisiones el consumidor y un mensaje para que tome decisiones el usuario en caso de ser necesario. Por eso es una buena práctica mostrar ese texto.
- Por otra parte el** {“VIEW”:{“FechaRealizacion”:{..}}}** le indica al consumidor como procesar este atributo o recurso. En este caso se indica que: \\ \\ 1. El tipo es fecha, por lo que el consumidor puede ofrecerle un formato apropiado o incluso un widget de calendario. El resultado debe ser si o si en el formato especificado por el WS \\ 2. El resultado de lo que el usuario ingrese debe ser colocado en el JSON de request nuevo en la posición que se indica. Las “/” separan claves. Es decir, en el ejemplo al **“REST”** debe agregarse una clave** “FechaRealizacion”** que contiene una clave **“value”**que vale la fecha que ingrese el usuario. \\ 3. Información de asistencia al usuario como el label del campo para ingresar la fecha. El error que ocacionó que el WS requiera este dato, etc.
|
=== Tipo string y timestamp. ===
Una propuesta para presentarle al usuario bien podría ser:
[[:desarrolladores:tipo_string_y_timestamp.png?720x243}}|{{ :desarrolladores:webservice_uso:tipo_string_y_timestamp.png?nolink&720x243 }}]]
=== Tipo list. ===
En lineas generales este criterio sirve para los tipos** texto y fecha.** Otro ejemplo interesante es el tipo **lista**. Siguiendo con el ejemplo podemos ver que hay un atributo **contexto ** en el response de un post vacío a ordenes:
| \\ Fracción de response \\ "REST": [], \\ "STATUS": { \\ "ERROR": { \\ "afiliado": [ \\ { \\ "code": 10010, \\ "message": "Sea mas especifico en la busqueda, se encontraron mas resultados de los permitidos" \\ }, \\ { \\ "code": 10060, \\ "message": "El atributo es requerido" \\ } \\ ], - - -"VIEW": { \\ "afiliado": { \\ "type": "list", \\ "label": "Seleccione un afiliado de la lista", \\ "path": "REST/afiliado", \\ "options": { \\ "lelWBHU685gZOTAWSh3OrO5XAT0XEa": "GUERRERO JUAN ANTONI|40506285720700|PAMI|", \\ "EduJfFqI1BOBgcYL8G4TXEd34MbGBd": "MINERVINI…. \\ } \\ }, \\ - - - |
Los criterios a aplicar sobre el **atributo ** afiliado son similares a los de **FechaRealizacion** vistos en el ejemplo anterior, aquí la diferencia es que el input o el entry que se le provee al afiliado es sobre una lista de opciones en las que se detalla en la sección “**opciones**” que mostrarle al afiliado para que elija y que devolver en la ruta especificada. Siempre se devuelve la clave y se muestra el valor \\ \\ [[:desarrolladores:tipo_list.png?616x264 }}|{{ :desarrolladores:webservice_uso:tipo_list.png?nolink&616x264 }}]]
Al igual que en el caso de **FechaRealizacion ** quedará en la **ruta ** especificada el valor que seleccione el usuario en este caso. Ya podemos apreciar que es el usuario quien mediante estos mecanismos simples puede ir construyendo el próximo request ya que se van completando las secciones del mismo.
=== Tipo recurso. ===
===== =====
Otro caso interesante para ver con ejemplos es el del tipo **recurso**. Veamos un ejemplo mas para poder formalizar una política.
| \\ Fracción de response \\ "REST": [], \\ "STATUS": { \\ "ERROR": { \\ - - - \\ "afiliados": { \\ "CODE": 10070, \\ "MESSAGE": "El recurso es requerido" \\ }, - - -"VIEW": { \\ - - - \\ "prescriptor": { \\ "type": "resource", \\ "label": "", \\ "resource": { \\ "MatriculaNacional": { \\ "path": "SEARCH/prescriptor/2/MatriculaNacional.contenga", \\ "type": "string", \\ "label": "Buscar con MatriculaNacional" \\ }, \\ "NombreCompuesto": { \\ "path": "SEARCH/prescriptor/3/NombreCompuesto.contenga", \\ "type": "string", \\ "label": "Buscar con NombreCompuesto" \\ }, - - - \\ }, \\ - - - |
El tipo **recurso ** es ni mas ni menos que una serie de atributos que definen un recurso cuando es imposible ofrecerlo en una lista. Por ejemplo, supongamos el ejemplo concreto del response que estamos analizando. El afiliado bien podría ser elegido de una lista, pero sería una lista con miles de opciones. Por lo que al no haber dato alguno y ser un dato necesario para instanciar la orden entonces se ofrece completar datos que buscarán un recurso afiliado adecuado. Si miramos la porción del response de **afiliados ** dentro de **VIEW ** veremos que está como siempre la clave “**tipo**” y una clave “**resource**” que a simple vista parece como una sección **VIEW ** mas pequeña!. La realidad es que no parece, es. **VIEW ** es una estructura recursiva. \\ La primer entidad de **VIEW ** está implícita y es de tipo **recurso**.
\\ [[:desarrolladores:tipo_recurso.png?400x308 }}|{{ :desarrolladores:webservice_uso:tipo_recurso.png?nolink&612x471 }}]]
A diferencia de los atributos anteriores (**FechaRealizacion ** y **Contexto**) acá podemos observar que el destino es dentro de la clave **“SEARCH”:{..}** en vez de **“REST”:{..}**. El WS está ofreciendo herramientas de búsqueda. Repasemos como iría quedando conformado el nuevo request que pudimos armar en función de un response al realizar un request vacío.
| \\ Nuevo POST a ws.test.suap.com.ar/procesador/do/V1.0/ordenes \\ "REST": { \\ “FechaRealizacion”:{“value”:”2018-07-02 00:00:00”}, \\ “Contexto”:{“value”:”Ambulatorio”}, \\ }, \\ "SEARCH": { \\ “prescriptor”:{ \\ “NombreCompuesto.contenga”:”Juan Perez”, \\ “DocNumero.contenga”:”123..”, \\ }, \\ } |
Podemos ir observando que el WS nos indicó:
* Qué falta.
* Cómo requerirlo al usuario.
* Cómo enviarlo al WS nuevamente.
Es decir, mediante una política sencilla, nos está ayudando a requerirle al usuario la información y a construir el request para enviar nuevamente el **POST.**
=== Tipo transpuesta/mucho a muchos. ===
Este tipo de widget representa relaciones entre recursos como el título lo indica. Mucho a muchos. Pensemos un poco como sería la incorporación de un conjunto de practicas a una orden en una especificación RESTfull. Por un lado para poder vincular una orden con un conjunto de items practica tendríamos que crear
* El recurso orden
* los recursos item
* vincular los recurso items con el recurso orden.
Esto sería asi porque para poder vincular el recurso orden con los items necesito los tokens. Es un problema de orden de creación. El WS no permite crear items de forma aislada.
**FALTA DOCUMENTAR**
\\