Buenas, en este post vamos a ver de forma rápida y sencilla cómo realizar un servicio con operaciones sobre una base de datos, a través del Enterprise Integrator de WSO2. Tradicionalmente estos servicios, denominados data services, se realizan como operaciones SOAP. Hoy veremos cómo hacerlos un poco más actuales, y desarrollarlos como servicios REST.
Para empezar deberemos tener un Enterprise Integrator arrancado y con un datasoure configurado. El data service lo podremos generar a través del asistente de la plataforma, pero yo os lo explicaré a través de ejemplos de código.
A continuación mostraremos un data service sencillo. Donde indicaremos el data source a utilizar, el cual previamente ya se ha configurado en el EI (en el ejemplo, LIBRARY será el nombre de dicho data source). El cual además tendrá una query sencilla a modo de ejemplo.
<data name="book_dataservices" transports="http https local"> <config id="LIBRARY"> <property name="carbon_datasource_name">LIBRARY</property> </config> <query id="getBook" useConfig="LIBRARY"> <sql>SELECT NAME, AUTHOR FROM BOOK WHERE ID = :id</sql> <result element="Books" rowName="book" escapeNonPrintableChar="true"> <element column="NAME" name="name" xsdType="STRING"/> <element column="AUTHOR" name="author" xsdType="STRING"/> </result> <param name="id" ordinal="1" sqlType="INTEGER"/> </query> </data>
Con esto aún no seremos capaces de obtener ningún dato. El siguiente paso será definir una operación o recurso del data service. Y aquí será donde radica la principal diferencia. Si queremos un data service con acceso SOAP deberemos configurar un objeto operation y si queremos que sea accesible como una API REST, deberemos configurar un objeto resource.
A la hora de crear un recurso, debemos indicar 4 valores:
A la hora de crear un recurso, debemos indicar 4 valores:
- resourcePath: El contexto del servicio donde también podemos indicar los path params.
- resource method: El método HTTP con el que invocamos el recurso.
- queryId: El identificador de la query asociado al recurso.
- queryParams: la asociación entre los path/query params de la invocación al recurso y los de la propia query.
A continuación mostraremos un ejemplo para la query anterior. En este ejemplo, pasaremos el identificador como un query param. Y para ello debemos indicarlo en el path.
<resource method="GET" path="book/{id}"> <call-query href="getBook"> <with-param name="id" query-param="id"/> </call-query> </resource>
A continuación veremos como obtener los datos de un objeto en base a su identificador. Una cosa muy importante en este tipo de data services es el uso de las cabeceras Accept y Content-Type.
A continuación vamos a realizar un POST.
La principal novedad a la hora de invocarlo, es el paso de la información hacia el data service. Debemos crear un objeto json cuyo nombre empieza con el guión bajo y el nombre del método HTTP y posteriormente el nombre del contexto (las barras se sustituyen por guiones bajos). Y cada parámetro de entrada de la query es un atributo del objeto JSON.
El método PUT es prácticamente igual
Y podemos invocarlo así
Por último solo quedaría el DELETE:
curl -kX GET 'https://localhost:8243/services/book_dataservices/book/3' \ -H 'Accept: application/json'
A continuación vamos a realizar un POST.
<query id="postBook" keyColumns="ID" returnGeneratedKeys="true" useConfig="LIBRARY"> <sql>INSERT INTO BOOK (NAME, AUTHOR) VALUES (?, ?)</sql> <result element="return" rowName="" useColumnNumbers="true"> <element column="1" name="ID" xsdType="integer"/> </result> <param name="name" ordinal="1" sqlType="STRING"/> <param name="author" ordinal="2" sqlType="STRING"/> </query> <resource method="POST" path="book"> <call-query href="postBook"> <with-param name="name" query-param="name"/> <with-param name="author" query-param="author"/> </call-query> </resource>
La principal novedad a la hora de invocarlo, es el paso de la información hacia el data service. Debemos crear un objeto json cuyo nombre empieza con el guión bajo y el nombre del método HTTP y posteriormente el nombre del contexto (las barras se sustituyen por guiones bajos). Y cada parámetro de entrada de la query es un atributo del objeto JSON.
curl -kX POST 'https://localhost:8243/services/book_dataservices/book' \ -H 'Content-Type: application/json' -H 'Accept: application/json' \ --data-raw '{ "_postbook": { "name": "AT", "author": "AT" } }'
El método PUT es prácticamente igual
<query id="putbook" returnUpdatedRowCount="true" useConfig="LIBRARY"> <sql>UPDATE BOOK SET NAME=?, AUTHOR=? WHERE ID = ?</sql> <result element="UpdatedRowCount" rowName="" useColumnNumbers="true"> <element column="1" name="ID" xsdType="integer"/> </result> <param name="name" sqlType="STRING"/> <param name="author" sqlType="STRING"/> <param name="id" sqlType="INTEGER"/> </query> <resource method="PUT" path="book"> <call-query href="putbook"> <with-param name="name" query-param="name"/> <with-param name="author" query-param="author"/> <with-param name="id" query-param="id"/> </call-query> </resource>
Y podemos invocarlo así
curl -kX PUT 'https://localhost:8243/services/book_dataservices/book' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ --data-raw '{"_putbook": {"name": "AT1","author": "AT1","id":3 } }'
Por último solo quedaría el DELETE:
<query id="deleteBook" useConfig="LIBRARY"> <sql>DELETE FROM BOOK WHERE ID = :id</sql> <result element="UpdatedRowCount" rowName="" useColumnNumbers="true"> <element column="1" name="ID" xsdType="integer"/> </result> <param name="id" ordinal="1" sqlType="INTEGER"/> </query> <resource method="DELETE" path="book/{id}"> <call-query href="deleteBook"> <with-param name="id" query-param="id"/> </call-query> </resource>
Y su invocación sería:
curl -kX DELETE 'https://localhost:8243/services/book_dataservices/book' \ -H 'Accept: application/json' -H 'Content-Type: application/json' \ --data-raw '{ "_deletebook": { "id": 3 } }'
No hay comentarios:
Publicar un comentario