+
+La petición realizada por el cliente (un simple GET HTTP con la latitud, longitud y el tipo de contenido esperado en la propia URL) llega al servidor. El tratamiento de esta petición depende del framework, lenguaje, etc que estemos utilizando en la aplicación que actúa como servidor Web. En nuestro caso, se trata de una aplicación escrita en PHP y que usa el Framework Symfony, por tanto debemos ceñirnos (si queremos desarrollar un código mantenible y legible) al modo que Symfony nos permite implementar servicios Web RESTful.
+
+En el Listado~\ref{list:PHPWebServiceRouting}) se muestra la parte del archivo routing.yml utilizado en este proyecto para configurar en Symfony el servicio Web RESTful que recibe la posición actual del usuario. Explicado de forma sencilla el archivo routing.yml en Symfony permite configurar diferentes URLs en las que la aplicación Web escuchará y asociar estas URLs a clases PHP que se encuentran en nuestra aplicación y que tratarán la petición del usuario y devolverán (si es necesario) una respuesta. En este caso es un servicio Web RESTful lo que se está configurando, pero en la práctica podría ser cualquier cosa, por ejemplo, una simple página web escrita en HTML.
+
+\lstset{language=bash, basicstyle=\small, breaklines=true, float=[P], floatplacement={P}, frame=single, captionpos=b, caption={Servicio Web RESTful en Symfony: definición}, label={list:PHPWebServiceRouting}}
+\lstinputlisting{source/PHPWebServiceRouting.yml}
+
+\begin{itemize}
+ \item La entrada \emph{url} define el formato de la dirección que manejará el servicio web (su URL) indicando mediante el uso de el carácter ``:'' que ese campo es una variable cuyo valor no es conocido a priori y tiene que venir dado por la petición GET HTTP desde el cliente.
+ \item La entrada \emph{param} indica el método que se ejecutará cuando llega una petición GET HTTP a la URL definida anteriormente.
+ \item \emph{sf\_format} indica el formato de los datos devueltos por el servicio Web. En nuestro caso se permite XML, JSON o YAML pero finalmente solo ha sido implementado JSON.
+ \item Por último la entrada \emph{sf\_method} hace referencia al tipo de método HTTP que se permitirá para hacer uso de este servicio Web.
+\end{itemize}
+
+Posteriormente hay que atrapar la petición GET HTTP para tratarla y devolver un resultado, este proceso se muestra en el Listado~\ref{list:PHPWebServiceActions}) donde se ejecuta el método definido en el Listado~\ref{list:PHPWebServiceRouting}). RESTful permite usar cookies pero únicamente para indicar si un usuario está autenticado o no, para este servicio Web en concreto es necesario que el usuario haya hecho \emph{log in} previamente en el servidor Web. Tal tarea se lleva a cabo en la aplicación Android, si el \emph{log in} es satisfactorio guardará la cookie recibida desde el servidor Web (desde la aplicación PHP) y la adjuntará en la cabecera de posteriores peticiones GET HTTP (usando AndroidHttpClient tal y como fue mostrado en el Listado~\ref{list:JavaHTTPGet}) Como el usuario está autenticado podemos averiguar el id asociado a ese usuario dentro del sistema (en la base de datos de la aplicación Web); en caso de no estar autenticado este método fallará y no devolverá nada.
+
+\lstset{language=PHP, basicstyle=\small, breaklines=true, float=[P], floatplacement={P}, frame=single, captionpos=b, caption={Código para el tratamiento del servicio Web}, label={list:PHPWebServiceActions}}
+\lstinputlisting{source/PHPWebServiceActions.php}
+
+El método que lleva a cabo todo el peso de búsqueda en base de datos de anuncios localizados en las cercanías del usuario es getAdsByGPSAndUserIdAndLanguageId. Si este método no devuelve nada, significa que o bien no hay anuncios en esas coordenadas geográficas o el usuario no se ha subscrito a categorías relacionadas con anuncios localizados en ese área en el cual se encuentra actualmente. El método getParameters() devuelve un array con los parámetros de entrada suministrados en el GET HTTP. En este caso, dichos parámetros se insertan directamente en la URL y fueron definidos en el Listado~\ref{list:PHPWebServiceRouting}) dentro de la entrada url como \emph{longitude} y \emph{latitude}.
+
+El Listado~\ref{list:PHPWebServiceModel}) muestra como haciendo uso del id del usuario dentro del sistema (lo conocemos porque tuvo que hacer previamente \emph{log in} y envía su cookie en cada petición GET HTTP al servicio Web), la latitud y la longitud se puede mediante peticiones a la base de datos averiguar si existen anuncios de interés en las cercanías del usuario. Actualmente el radio de acción al rededor del cual se buscará en la base de datos PostGIS por posibles anuncios de interés se define directamente en el código PHP; en posteriores implementaciones sería posible por ejemplo, que en función de si el servicio es premium o no, el usuario pueda seleccionar el radio de acción al rededor del cual desea que se busquen anuncios en su posición actual.
+
+\lstset{language=PHP, basicstyle=\small, breaklines=true, float=[P], floatplacement={P}, frame=single, captionpos=b, caption={Código para la búsqueda de anuncios en la base de datos PostgreSQL/PostGIS}, label={list:PHPWebServiceModel}}
+\lstinputlisting{source/PHPWebServiceModel.php}
+
+El método ST\_DWithin del Listado~\ref{list:PHPWebServiceModel}) es un método especial definido por PostGIS que permite hacer búsquedas en la base de datos PostgreSQL de posiciones geográficas que se encuentren dentro de una circunferencia con radio \emph{radius} y centro marcado por el tipo SRID 4326 o también llamado WGS 84 que son las siglas en Inglés para \emph{World Geodetic System 84}. WGS 84\footnote{La Wikipedia proporciona una buena introducción al estándar WGS: \url{http://en.wikipedia.org/wiki/WGS84}} es el sistema usado por el \emph{Global Positioning System} o GPS que es precisamente desde el cual estamos recibiendo datos a través del dispositivo móvil utilizado por el usuario.
+
+Como también se puede observar en el Listado~\ref{list:PHPWebServiceModel}) realizamos peticiones directamente a la base de datos. El objetivo de llevar a cabo las peticiones de este modo es disminuir la sobrecarga de código y por tanto de ciclos de CPU para implementar en el servidor cada petición al servicio Web realizada por los clientes. Este código será usado por muchos usuarios de forma concurrente, por tanto es necesario que se ejecute tan rápidamente como sea posible. Ganamos velocidad pero perdemos legibilidad y mantenibilidad del código.
+
+Se requiere de varias peticiones a la base de datos para poder obtener al final un array con los anuncios (findOneByAdIdAndLanguageId devuelve objetos PHP del tipo Doctrine\_Record\footnote{Sobre objetos Doctrine ver: \url{http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/component-overview.html}}) que se encuentran alrededor de la localización geográfica del usuario (primera consulta a la base de datos) y que están relacionados con categorías a las cuales el usuario se encuentra asociado (segunda consulta a la base de datos).
+
+Y finalmente en el Listado~\ref{list:PHPWebServiceView}) se genera el código JSON que será recibido y procesado por la aplicación cliente Android tal y como se mostró en el Listado~\ref{list:JavaHTTPJSONtreatment})
+
+\lstset{language=PHP, basicstyle=\small, breaklines=true, float=[P], floatplacement={P}, frame=single, captionpos=b, caption={Código para la generación de datos en formato JSON}, label={list:PHPWebServiceView}}
+\lstinputlisting{source/PHPWebServiceView.php}