Sobre qué son las CORS o cómo tirarte de los pelos cuando aparecen.

Pongo la mano en el fuego que durante tu vida como programador has tenido que pelearte con las CORS alguna vez, verdad?

Si ya lo has hecho sabrás lo importantes que son y el por culo que dan, pero en cambio, si ni siquiera te suena este término pues… enhorabuena supongo.

Si no lo conoces y te dedicas al desarrollo web es algo que vas a necesitar saber en futuro así que dale.

Eso si, como siempre digo, en mi experiencia como desarrollador lo que mas me ha costado siempre es esto y las expresiones regulares. Esa cosas que se te atasca y no hay manera. Pues eso.

Pero no te preocupes si vas de nuevo porque conociendo los fundamentos de las CORS y a la mínima que hayas resuelto 3 errores de este tipo, te saldrán como churros 😉

 

¿Qué son las CORS?

A ver, para empezar la palabra CORS es una sigla de Cross-Origin Resource Sharing. Esto es, traducido al castellano Intercambio de recursos de Origen Cruzado. 

Pero no nos dice mucho. Vayamos a la wikipedia y a partir de ahí desarrollamos.

Intercambio de recursos de origen cruzado o CORS es un mecanismo que permite que recursos restringidos (como por ejemplo, las tipografías) de una página web puedan ser solicitados desde un dominio diferente por fuera desde el cual el primer recurso fue expuesto.

CORS define una forma en la cual el navegador y el servidor pueden interactuar para determinar si es seguro permitir una petición de origen cruzado.​ Esto permite tener más libertad y funcionalidad que las peticiones de mismo origen, pero es adicionalmente más seguro que simplemente permitir todas las peticiones de origen cruzado.

 

Creo que se entiende bastante bien pero para resumir consiste en que una página «no puede» cargar datos o elementos de otra página diferente.

Y pongo entre comillas «no puede» porque precisamente las CORS definen una política de seguridad que nos permite jugar con los recursos.

Obviamente todo esto tiene que ver con el desarrollo de páginas web y/o aplicaciones web. A la mínima que te pongas a hacer algo para la web vas a utilizar javascript si o si y lo sabes.

julio iglesias y lo sabes

Y en el fondo también tirarás de Ajax. Y si no piensa en todos los frameworks de front como funcionan en su base. Peticiones Ajax una y otra vez.

Pero antes de que apareciera el protocolo de las CORS no se podían cargar datos por Ajax en una página A desde otra página B.

Me explico.

Desde gorkamu.com yo no podía acceder a los recursos de forocoches.com, por ejemplo. Sólo se podía acceder a los recursos que estuvieran alojados bajo un mismo dominio. Es decir:

  • gorkamu.com/css/styles.css
  • gorkamu.com/js/form.js

¿Se entiende no?

Pues eso, que no se podía.

Aunque realmente había formas para «saltarse» esta limitación utilizando JSONP pero no eran genéricas desde luego…

 

¿Cómo funcionan las CORS?

Vale ahora pongámonos técnicos porque vamos a entrar con el tema del preflight y cómo afectan a las CORS.

Cuando una página web intenta conectar con otra para acceder a un recurso, ahí se está produciendo una petición HTTP. Las hay de distintos tipos pero todas ellas llevan cabeceras en su petición.

Aquí te explico un poco mas en detalle qué es y cómo funciona el protocolo HTTP.

Pues justo antes de que se llegue a realizarse la petición tu navegador automáticamente la intercepta para enviar antes el una primero.

Esta pre-petición automática es conocida porque se ejecuta bajo el método OPTIONS y no tiene cuerpo, sólo envía las cabeceras.

Las cabeceras o headers que se envían por parte del navegador le dan información al servidor sobre qué quiere hacer.

Así pues, en función de lo que nos responda el servidor después de esta primera pre-llamada, la petición original podrá continuar o por el contrario se bloqueará y arrojará un error.

prelight de CORS

Fíjate bien porque tal y como ves, este error de CORS también se produce por intentar acceder a un puerto diferente del 80 o 443. Aunque formen parte del mismo dominio.

Imagínate que abres Google Drive y haces una petición cualquiera. Por ejemplo el guardar un documento nuevo.

Si inspeccionas desde las herramientas para desarrolladores de tu navegador podrás ver algo tal que así:

Request headers en CORS

Esto que ves es la pantalla en la que puedes comprobar las peticiones HTTP que se están produciendo para esa página. Aquí puedes ir viendo una por una de qué tipo es y qué datos envía o recibe.

En la parte de Request Headers vemos las cabeceras que se han enviado en el preflight de la petición original. Hay varias de ellas pero quédate con las siguientes:

  • access-control-request-headers: authorization, x-goog-authuser
  • access-control-request-method: POST
  • origin: https://drive.google.com

 

La primera cabecera, access-control-request-headers, es una cabecera que se envía durante el proceso de preflight y le permite saber al servidor qué otras cabeceras HTTP van a usarse cuando se realice la petición. En el ejemplo se utilizan dos: authorization para autenticarse bajo Bearer o oAuth lo mas probable y la segunda x-goog-authuser para autenticarse contra Google.

La cabecera access-control-request-method le indica al servidor que métodos o acciones puede llegar a hacer la petición. En el ejemplo indica que solo va a ejecutar un método POST pero se pueden añadir tantas igual como de verbosa sea la API a la que quiere acceder.

La última cabecera, origin, le dice al servidor desde donde se realiza la petición. Si este host es válido para el servidor permitirá realizar la petición. Si por el contrario no reconoce el valor de la cabecera origin echará para atrás la request.

Ahora bien, si el servidor reconoce y valida estas cabeceras de la petición preflight podrá ejecutarse la petición original, sino no.

¿Pero y qué es lo nos responde el servidor?

Cabeceras CORS de respuesta
Cabeceras CORS de respuesta

 

Aquí las cabeceras de respuesta. Fíjate que devuelve con las mismas que hemos visto pero con alguno de sus valores ampliado. Por ejemplo la cabecera access-control-request-method, que a diferencia de lo que se enviaba en la petición, nos responde que acepta los métodos GET, POST y OPTION.

Esto es, para toda la aplicación los únicos métodos que pueda ejecutar cualquier petición serán esos tres únicamente. En el caso de que fuera una API a lo que se consulta, no sería muy verbosa si la entendemos como una RESTFull API…

 

¿Cómo habilitar las CORS?

Si ya has entendido como funciona esta política y ves el potencial que tiene probablemente quieras empezar a usarla ya.

Antes de nada piensa que si tu perfil es puramente backend estás de enhorabuena ya que la película de habilitar las CORS en tu API va a caer de tu parte si o si.

El gran trabajo lo tienes que hacer tu.

Y por parte de la gente de front tan solo hay que añadir las cabeceras a las peticiones y del resto ya se encarga el navegador (y el programador backend 😂)

Existe una página de referencia para saber cómo habilitar las CORS en diferentes tecnologías. La web en cuestión es esta, ya puedes guardártela bien en los marcadores…

 

Utilizar CORS en Apache

Apache, uno de los servidores mas utilizados en el mundo web. Aquí tienes un ejemplo de cómo usar esta política con este servidor.

Para añadir la autorización CORS a las cabeceras de Apache tan solo añade la siguiente línea dentro de la etiqueta <Directory>, <Location>, <Files> o <VirtualHost> de tu configuración

  Header set Access-Control-Allow-Origin "*"

Esta línea lo que hace es permitir las conexiones desde todos los orígenes. También puedes añadirla en tu .htaccess

Para asegurarte de que se ha aplicado correctamente la configuración puedes comprobarlo tirando la siguiente línea en la consola:

apachectl -t

Una vez que la veas aplicada tan solo te tocará reiniciar el servidor y listo!

sudo service apache2 reload

 

Añadir las CORS en NGINX

Para el que no lo conozca Nginx es otro servidor web bastante utilizado. Aunque también podemos configurarlo para ser utilizado como un Proxy-Inverso o como un balanceador de carga entre otras cosas.

Últimamente en mis desarrollos lo estoy utilizando mas que Apache incluso. Para habilitar las CORS en Nginx tienes a continuación la configuración necesaria.

#
# Wide-open CORS config for nginx
#
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
}

 

Habilitar las CORS en PHP

Como bien he dicho mas arriba, Apache es uno de los servidores web mas utilizado y es por supuesto el servidor por excelencia para el lenguaje PHP.

De hecho un stack típico es el de LAMP, MAMP o WAMP que no deja de ser otra cosa que Linux o MacOS o Windows junto con Apache, Mysql y PHP por sus siglas….

Si por un casual no tienes acceso a editar la configuración de Apache siempre puedes habilitar las CORS en PHP añadiendo la siguiente cabecera:

 <?php
 header("Access-Control-Allow-Origin: *");

Esta cabecera la tendrás que poner antes de cualquier función que devuelva una respuesta.

 

Usar CORS con Express

El último de los ejemplos es habilitar esta política con Express. Un framework Javascript super utilizado principalmente para el desarrollo de APIs. Todo corriendo bajo Node claro está!

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

 

Con esto llegamos al final del artículo.

Espero que te haya quedado claro. A mi al principio me costó entenderlo y me tiraba de los pelos cada vez que me salía un error de estos al realizar una petición a través de Ajax a un recurso externo…

Pero no te preocupes, al segundo error que te salga de este tipo ya sabrás solucionarlo y sino siempre puedes preguntarme a través de twittah.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

A pastar!

Utilizando contenedores Docker con Nodejs

Seguimos con los artículos dedicados al desarrollo de aplicaciones haciendo uso de javascript del lado del servidor. En este post vamos a ver cómo podemos aprovecharnos de la tecnología de contenedores Docker con NodeJs.

En un artículo anterior ya hice una comparativa entre Docker y Vagrant pero para el que venga de nuevas y antes de entrar en materia tenemos que conocer qué es Docker.

Según la Wikipedia:

Docker es un proyecto de código abierto que automatiza el despliegue de aplicaciones dentro de contenedores de software, proporcionando una capa adicional de abstracción y automatización de Virtualización a nivel de sistema operativo en Linux.

¿Eing?.. ¿Se te ha quedado cara de bobo tras leer eso? No te preocupes que voy a tratar de explicarte qué es Docker desde otra aproximación.

Imagina que puedes construir toda una aplicación funcional, con sus librerías, assets y dependencias de manera aislada.

Esta aplicación siempre te va a funcionar en cualquier ordenador en el que esté alojada. Ningún conflicto mas entre versiones ni librerías perdidas.

Olvídate de eso.

Tu metes tu aplicación en una cajita y te aseguras que dejes donde dejes esa cajita siempre va a funcionar.

Pues algo así es Docker y así es cómo nos ayuda.

Nos permite aislar los componentes de la aplicación del resto del sistema operativo asegurándonos que siempre va a funcionar.

Obviamente el uso de Docker está muy ligado tanto a entornos de desarrollo como a despliegues de aplicaciones, pero ahora que ya tienes una idea aproximada de qué son estos contenedores vamos a ver cómo podemos usar Docker con Nodejs.

Aprender a usar Docker con NodeJs

La finalidad de este ejemplo va a ser enseñarte como conseguir que tu aplicación NodeJs corra dentro de un contenedor Docker. Nos vamos a centrar bajo la óptica del entorno de desarrollo no en la de despliegue en producción así que si usas este ejemplo para hacer una subida a producción y peta luego no quiero represalias 😛

Podríamos utilizar el ejemplo que hemos venido desarrollando en artículos anteriores sobre cómo construir una aplicación NodeJs pero como el fin último de este articulo es aprender a configurar Docker con NodeJs vamos a crearnos una aplicación pequeñita desde cero.

Docker nos va a permitir empaquetar toda nuestra aplicación junto con sus librerías y dependencias en una unidad estandarizada y atómica, esto es lo que se conoce como contenedor docker.

Otro concepto importante del universo docker que hay que conocer son las imágenes y esto es el software que se va a cargar dentro del contenedor previamente creado.

Creando una aplicación NodeJs

Lo primero de todo, créate en tu workspace un directorio para la aplicación. Al mío yo le he llamado directorio_para_aplicación_nodejs_guay_con_docker. ¿Bastante intuitivo no creéis?

Bien, en este directorio residirán todos los ficheros de tu aplicación pero el primer fichero necesario para empezar es el package.json el cual sirve de descripción de tu aplicación y de todas sus dependencias.


{
"name": "app_nodejs_con_docker",
"version": "1.0.0",
"description": "Ejemplo de uso de Docker con Nodejs",
"author": "Gorkamu el puto amo <gorkamu@elputoamo.com>",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.13.3"
}
}

view raw

package.json

hosted with ❤ by GitHub

Bien, una vez hecho esto vamos a crear el fichero que definirá la aplicación web haciendo uso del framework Express. Esto es, el fichero server.js.


'use strict';
const express = require('express');
// Constantes
const PORT = 8080;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', (req, res) => {
res.send('Que pasa gandul!\n');
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

view raw

server.js

hosted with ❤ by GitHub

A continuación vamos a ver cómo podemos crear esta aplicación tan tonta dentro de un contenedor de Docker usando para ello la imagen oficial aunque antes de eso es necesario que creemos la imagen Docker de la aplicación.

Creando el fichero Dockerfile

En el mismo directorio en el que hemos puesto los dos ficheros anteriores, vamos ahora a crear uno nuevo que se llame Dockerfile.

Este fichero contendrá las instrucciones necesarias para que Docker sepa cómo ha de construir la imagen que albergará la aplicación NodeJs.

Este fichero se ve tal que así:


FROM node:argon
# Creando el directorio de la aplicación
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Instalando todas sus dependencias
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
EXPOSE 8080
CMD [ "npm", "start" ]

view raw

Dockerfile

hosted with ❤ by GitHub

Pero vamos a ir paso a paso:

  • La primera línea indica que tipo de imagen queremos construir. En este caso estamos haciendo uso de la versión de largo soporte (LTS) de argon para NodeJs. Puedes ver otras imágenes desde Docker Hub.
  • Las siguientes líneas le dicen a Docker que tiene que crear un directorio bajo /usr/src/app (hablando siempre desde dentro del contenedor) y establece este path como su directorio de trabajo
  • Después se le dice a Docker que copie el fichero de definición de la aplicación NodeJs (package.json) al directorio de trabajo creado en previamente y que ejecute las dependencias que tiene la aplicación. Al usar node:argon (primera línea) ya tenemos disponible NPM y NodeJs.
  • Ten presente que en lugar de copiar todo el directorio de trabajo tan solo estamos copiando el fichero package.json dentro del contenedor. Esto nos permite aprovecharnos de las diferentes capas cacheadas de Docker. Si quieres profundizar un poquito mas y saber que carajos son estas capas cacheadas échale un vistazo a este artículo.
  • La siguiente línea o instrucción le dice a Docker que copie todo el directorio de fuera del contenedor al directorio de dentro del contenedor. Es decir, en este ejemplo solo copiará el fichero server.js pero si tu aplicación tuviera mas cosas las copiaría todas pa’ dentro.
  • También tenemos que exponer un puerto a través del cual se comunicará el mundo exterior con nuestro contenedor. Es típico poner siempre el puerto 8080 aunque puedes elegir el que mas te guste siempre y cuando no esté dentro de los Well-Know Ports.
  • Por último pero no menos importante, hay que definir el comando a ejecutar a través de la terminal para nuestra aplicación. En el ejemplo usamos el inicio típico y básico de una aplicación NodeJs el cual ejecutará el fichero server.js.

Poh’ ya está. Con esto ya tenemos definido el fichero que dará vida a nuestra imagen Docker.

Construyendo nuestra imagen

Para ello vamos a ir al directorio en el que tenemos el fichero Dockerfile y ejecutaremos en una terminal el siguiente comando para que Docker construya la imagen Docker con Nodejs.

docker build -t node-web-app .

El parámetro -t del comando anterior te permite darle un nombre a la imagen por lo que es mas fácil después encontrar la imagen al hacer uso de docker images. A nuestra imagen la hemos llamado node-web-app, también muy original… xD

Al listar las imágenes disponibles con docker images tendríamos que ver lo siguiente:

$ docker images

# Example
REPOSITORY                      TAG        ID              CREATED
node                            argon      539c0211cd76    3 weeks ago
node-web-app                    latest     d64d3505b0d2    1 minute ago

Corriendo nuestra imagen Docker

Aquí hay varias opciones de configuración al correr una imagen que puedes consultar en la documentación oficial de Docker pero para no liarnos mas ejecuta el siguiente comando:

$ docker run -p 49160:8080 -d node-web-app

La opción -d le indica a Docker que tiene que ser ejecutado en modo detached, esto es, que corra el contenedor en segundo plano. Por otro lado, la opción -p lo que permite es redirigir todas las consultas desde un puerto público hasta el puerto privado del contenedor que hemos definido en el fichero Dockerfile.

En este caso estamos mapeando el puerto 49160 con el puerto 8080.

Una vez hayas ejecutado el comando anterior ya tendrás tu contenedor Docker con NodeJs corriendo satisfactoriamente y podrás acceder a tu aplicación a través de http://localhost:49160

Si hacemos una petición curl a la url anterior obtendremos lo siguiente:

$ curl -i localhost:49160

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
Date: Sun, 02 Jun 2013 03:53:22 GMT
Connection: keep-alive

Que pasa gandul!

Como veis ya tenemos nuestra aplicación corriendo. Ha sido facilísimo configurar Docker con NodeJs pero por si acaso alguno tiene dudas o se ha liado en algún punto y me quiere preguntar algo hacedlo por favor en la sección de comentarios o en twitter a través del siguiente banner.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

Hasta la vista chumachos!

Cómo hacer una API REST con Node.js

En artículos anteriores hemos visto cómo hacer la primera configuración de las herramientas que vamos a instalar así como a organizar nuestro proyecto utilizando el patrón Modelo-Vista-Controlador. Pues bien, hoy toca entrar en materia y vamos a comenzar a hacer una API REST con Node.js.

Un primer paso necesario para seguir estudiando Node.js y una buena base para que después podamos crear una aplicación SPA, o consultar la API desde un proyecto Symfony o para hacer que nuestra aplicación móvil pueda explotar esos datos oooo yo que sé…. las posibilidades son infinitas así que empecemos!

Cómo hacer una API REST con Node.js

A lo mejor a mas de uno esto de hacer una API REST con Node le suena a chino así que lo mejor que podemos hacer es ver primeramente qué es eso de una API REST.

¿Qué es una API REST?

Pues es lo que se conoce como una interfaz de comunicación entre clientes que utilicen el protocolo HTTP. Para que se entienda, es el canal por el cual tu móvil le dice a los servidores de Clash Royale que has abierto un cofre y te ha tocado el mago eléctrico o por ejemplo es el canal que utiliza Instragram para subir las fotos que haces con tu smartphone a sus servidores.

¿Se entiende el concepto?

Hoy en día podemos encontrar usos de APIs en casi toda cosa tecnológica que nos imaginemos pero el concepto de API no es nuevo ya que hace años existía otro tipo de APIs que parecía ser el rey del desarrollo. Hablo de SOAP y su intercambio de datos mediante XML. Hasta que debido a su facilidad llegaron las API REST y el intercambio mediante JSON.

Principalmente con una API REST vamos a echar mano de lo que se conoce como verbos HTTP. En concreto 4 y cada uno de estos verbos los utilizaremos para una acción u operación diferente con los datos que queremos manipular.

Así pues:

  • Cuando queramos subir una imagen nueva a Instragram utilizaremos el método POST del protocolo HTTP.
  • Cuando queramos saber cuántos seguidores tenemos en Twitter utilizaremos el método GET del protocolo HTTP.
  • Cuando queramos eliminar nuestro último estado de Facebook utilizaremos el método DELETE del protocolo HTTP.
  • Cuando queramos actualizar la foto de perfil de Snapchat utilizaremos el método PUT del protocolo HTTP.
  • Cuando queramos ver la lista de seguidores de VK utilizaremos el método GET del protocolo HTTP.

Hasta aquí esto es lo mínimo que podemos hacer con una API REST pero si quieres saber mas te recomiendo que le eches un vistazo a este artículo en el que se explica muy bien toda esta película, que nosotros nos vamos a poner a hacer ya una API REST con Node.js 😀

Cuatro verbos para dominarlos a todos

¿Os acordáis de la aplicación sobre álbumes musicales que empezamos a crear en los artículos anteriores? Si no te acuerdas o todavía no los has visto retrocede un poquito en el tiempo desde este enlace y desde este y cuando los hayas terminado vuelve aquí para seguir con la API REST con Node.js

Pero para el que si que se acuerde mediante el patrón MVC llegamos a organizar los ficheros de nuestro proyecto de una forma lógica y funcional ¿no?

También te acordarás de que hicimos un pequeño controlador para probar ¿no? De hecho llegamos a definir los métodos mínimos que tiene que tener nuestra API pero la gran mayoría de estos métodos lo único que hacia era recibir los datos de la request y devolverlos en la response. No había lógica de negocio alguna.

Pues ha llegado el momento de darle cuerpo a esos métodos 🙂

Método GET, consultar datos en una API REST con Node.js

Este es el primer verbo que vamos a ver de nuestra API REST con Node.js y es que tiene dos aplicaciones. Por un lado podemos utilizarlo para que nos devuelva un listado de elementos y por otro lado si le pasamos un identificador (lo mas normal debido a su unicidad) obtendremos los datos de un solo registro.

Aclaro que no es necesario pasar un id, podemos pasarle cualquier parámetro aunque en los métodos tipo getBy lo mas normal es pasarle el identificador.


var Album = require('../models/album');
function getAlbum(req, res){
var albumId = req.params.id;
Album.findById(albumId, function(err, album) {
if(err) {
res.status(500).send({message: 'Error 500 al devolver el album'});
}else{
if(!album){
res.status(404).send({message: 'No hay album'});
}else{
res.status(200).send(album);
}
}
});
}
function getAlbumes(req, res){
Album.find({}).sort('-_id').exec((err, albumes) => {
if(err){
res.status(500).send({message: 'Error 500 al devolver los albumes'});
}else{
if(!albumes){
res.status(404).send({message: 'No hay albumes'});
}else{
res.status(200).send({albumes: albumes})
}
}
});
}

view raw

album.js

hosted with ❤ by GitHub

Fijaos, aquí tenemos el ejemplo de estos dos métodos GET de la API y que nos devolverán ya sea un elemento o varios elementos. Pero hay varias cosas importantes que explicar:

  1. Hay que incluir el modelo, eso se hace en la primera línea del código anterior mediante un require.
  2. Mediante la sentencia req.params.id de la linea 4 estamos accediendo al valor que le pasamos a la ruta como parámetro.
  3. En la línea 6 encontramos el método findById() que es definido por el ORM de Mongoose y que nos provee de una capa de abstracción para explotar datos. Este método acepta el identificador que ha de buscar y una función de callback.
  4. Línea 20 encadenamos el método find() y el método de ordenación sort(). Si al método find() no le pasamos ningún argumento tan solo un objeto vacío por defecto nos sacará todos los registros de ese modelo de nuestra base de datos. Por otro lado, el método sort() espera un argumento por el cual ordenar el listado.

Estos dos métodos de nuestra API matchearán con las siguientes rutas (recuerda, has de tenerlas definidas)

Método POST, guardar datos en una API REST con Node.js

Bien, el siguiente método que vamos a construir es el que se encarga de guardar datos y va a ir por POST.


function saveAlbum(req, res){
var album = new Album();
var params = req.body;
album.title = params.title;
album.band = params.band;
album.genre = params.genre;
album.year = params.year;
album.save(function(err, albumStored){
if(err){
res.status(500).send({message:'Error al guardar el album'});
}else{
res.status(200).send({album: albumStored});
}
});
}

view raw

album.js

hosted with ❤ by GitHub

  • Si antes accedíamos a los argumentos pasados por GET en la ruta mediante la sentencia req.params.id, ahora para obtener los valores pasados por el método POST tenemos que hacer uso de la sentencia req.body (línea 3)
  • Seteamos los valores de la instancia del modelo con lo que nos ha traído la petición POST de la línea 5 a la línea 8.
  • Hacemos uso del método definido por Mongoose save() para guardar estos datos. Este método acepta una función de callback que recibirá el error en caso de producirse o el objeto ya almacenado.
  • Lo demás es hacer unas comprobaciones mínimas para asegurar la integridad de los datos y a correr 🙂

Método PUT, actualizar datos en una API REST con Node.js


function updateAlbum(req, res){
var params = req.body;
var albumId = req.params.id;
Album.findByIdAndUpdate(albumId, params, function(err, album){
if(err){
res.status(500).send({message: 'Error 500 al actualizar el album'});
}else{
res.status(200).send(album);
}
});
}

view raw

album.js

hosted with ❤ by GitHub

Este es el método de nuestra API que se va a encargar de actualizar datos.

  • Va a recibir los datos a actualizar mediante POST (línea 2)
  • Va a recibir el identificador del objeto a actualizar mediante GET, a través de la URL (línea 3)
  • El método findByIdAndUpdate() nos es provisto por el ORM Mongoose y acepta el identificador del objeto a actualizar, los datos a actualizar y una función de callback con el error (si es que hay alguno) y el objeto ya actualizado.

He de aclarar que gracias al middleware body-parser y que ya aprendimos a instalar en los artículos anteriores, todo lo que nos llegue por POST es transformado en objeto automáticamente, así podemos manipular los parámetros de una forma bien sencilla.

La URL definida para este método ha de ser de la siguiente forma:

Método DELETE, borrar datos en una API REST con Node.js

El último método del CRUD de nuestra API REST con Node.js es el método que se va a encargar de borrar y que funciona a través del método DELETE del protocolo HTTP.


function deleteAlbum(req, res){
var albumId = req.params.id;
Album.findById(albumId, function(err, album){
if(err){
res.status(500).send({message: 'Error 500 al devolver el album'});
}else{
if(album){
album.remove(err => {
if(err){
res.status(500).send({message: 'Error 500 al borrar el album'});
}else{
res.status(200).send({message:'El album se ha borrado'});
}
});
}else{
res.status(400).send({message:'No hay album'});
}
}
});
}

view raw

album.js

hosted with ❤ by GitHub

  • Este método aceptará un único argumento que se pasa por la URL (el identificador del objeto) y que recogemos mediante la sentencia req.params.id (línea 2)
  • Gracias al ORM Mongoose podemos hacer uso del método findById() para encontrar el objeto que coincida con el identificador pasado por parámetro (línea 4).
  • Gracias al método remove() podemos eliminar el objeto solicitado (línea 9)

Con esto ya tenemos los 5 métodos necesarios para que el CRUD de nuestra API REST con Node.js funcione pero claro, necesitamos un modelo de datos para que transforme los datos que recibimos en objetos que podamos manejar mas facilmente.

Ademas que realmente el modelo es necesario para que corran los códigos anteriores…. 😛


'use strict'
var mongoose = require('mongoose');
var AlbumSchema = new mongoose.Schema({
title: String,
band: String,
genre: String,
year: String,
});
module.exports = mongoose.model('Album', AlbumSchema);

view raw

album.js

hosted with ❤ by GitHub

Ea ahí tenéis el modelo de datos. Ese fichero ha de situarse en el directorio de models según la definición del patrón Modelo-Vista-Controlador y que aprendimos en el artículo anterior.

Vale Gorka, ya hemos aprendido a construir una API REST con Node.js perfecto, pero ahora… ¿cómo la probamos?

Pueeees para probar la API vamos a hacer uso de una extensión muy buena que se llama Postman y que podemos descargar desde aquí si utilizas Chrome.

He grabado un vídeo para que veáis cómo se usa.

Cómo organizar un proyecto Node.js según MVC

Que Node.js sea una moda de desarrollo (esperemos que haya venido para quedarse) no lo discute nadie y como no podía ser de otra forma en esta serie de artículos vamos a aprender a trabajar con este entorno. Ya hemos visto los conceptos básicos en un post previo pero en este nuevo artículo vamos a ver como organizar un proyecto node.js siguiendo un patrón de diseño muuuuy conocido, el MVC.

Cómo organizar un proyecto Node.js de la mejor forma

Antes de entrar en materia deberías saber qué son los patrones de diseño.

Un patrón de diseño es un conjunto de reglas que nos indican cómo tenemos que organizar los ficheros de un proyecto para que este sea efectivo, reutilizable y escalable y siempre buscando la solución a un problema dado.

Existen miles de patrones de diseño diferentes y cada uno se ajusta a una casuística dada pero pongo la mano en el fuego si digo que en el ámbito del desarrollo web el que mas se utiliza es el patrón MVC.

Todos los que trabajamos con frameworks web como podrían ser Spring, Symfony o Angular (por citar diferentes tecnologías…) sabemos qué es el patrón Modelo-Vista-Controlador pero si has caído nuevo en este artículo y no sabes muy bien de que te hablo te recomiendo que le eches un vistazo a esta página de la Wikipedia.

Una vez que te hayas leído la entrada y entiendas el concepto de patrón MVC vamos a empezar a organizar nuestro proyecto Node.js 🙂

Definiendo la estructura básica de la aplicación

Deja de preguntarte ya cómo organizar un proyecto Node.js y dirígete al directorio que contendrá tu aplicación.

Ahí inicializaremos el proyecto con el comando npm init con el objetivo de crear el package.json que definirá toda nuestra aplicación. Cuando el comando termine y tengamos los ficheros básicos creados vamos a montar los siguientes directorios: /controllers,  /models y /routes

  • Directorio controllers: aquí guardaremos los ficheros que se encargarán de controlar cada parte de nuestra aplicación. Tenemos que ser capaces de abstraernos y saber atomizar la app y en consecuencia crear un controlador para cada una de estas partes. Los controladores contendrán la lógica de negocio.
  • Directorio models: en este directorio vamos a guardar lo que son los modelos de datos de la aplicación. Si tu aplicación trata sobre discos de música aquí crearemos una entidad con todas sus propiedades y métodos. Es lo que en Symfony se conoce como Entidad, en Java una POJO y en PHP una POPO.
  • Directorio routers: para hacer mas mantenible la exposición de rutas de cada controlador de tu aplicación en este directorio vamos a guardar la definición de estas rutas. Piensa que si estas construyendo una API a poco que sigas el modelo de API Restful como mínimo vas a tener 4 rutas por cada controlador (método GET, método POST, método PUT y método DELETE)

Una vez creados los directorio mínimos pasaremos a crear el fichero entrypoint (index.js) y el fichero de configuración de la aplicación.

En el fichero que hace la función de punto de entrada de nuestra aplicación, el fichero index.js, vamos a poner la configuración del servidor y a levantarlo.


'use strict'
var app = require('./app');
var port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server running in http://localhost:${port}`);
console.log('Defined routes:');
console.log(' [GET] http://localhost:3000/&#39;);
});

view raw

index.js

hosted with ❤ by GitHub

Pero… y ¿cómo podemos hacer que este fichero «llame a otros»?

Pues como se ve en la línea numero 3 del script haciendo uso del require le estamos indicando a node que queremos que nos cargue el core de nuestra aplicación pero con esto no es suficiente ya que tenemos que indicar algo mas que veremos a continuación.


'use strict'
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var api = require('./routes/favorito');
// Convierte una petición recibida (POST-GET…) a objeto JSON
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.use('/api', api);
// Exportar la variable 'app' que contiene express para poder usarla-requerirla en otros ficheros
module.exports = app;

view raw

app.js

hosted with ❤ by GitHub

Este fichero es en el que configuraremos todos los aspectos de nuestra aplicación.

Como puedes leer, en el script estamos cargando el framework express, cargamos el middleware body-parser y si te fijas en la línea 7 cargamos el archivo de rutas.

A raíz de la pregunta anterior, si queremos hacer que un fichero «llame a otro», a parte de hacer uso de la sentencia require en el fichero destino tenemos que exportarlo mediante el mecanismo de module.exports (última línea)

Una vez exportado ya podremos utilizarlo en cualquier parte de la app siempre y cuando lo carguemos con require.

Vale, hasta aquí todo correcto. Vamos a ver ahora como organizar un proyecto Node.js con sus rutas, sus controladores y sus modelos de datos.

Definiendo uno de los controladores de nuestra app

El controlador es el encargado de contener toda la lógica de negocio de nuestra aplicación. Tiene que actuar como una caja negra, le entran unos datos, los procesa y nos devuelve otros datos.

Hay varias formas de plantear y crear un controlador pero para el ámbito organizativo (no programático) de este artículo vamos a hacer funciones en lugar de clases, solo tenemos un controlador.


'use strict'
function getAlbum(req, res){
var id = req.params.id;
res.status(200).send({
data: id,
});
}
function getAlbums(req, res){
res.status(200).send({
data:albums
});
}
function saveAlbum(req, res){
var params = req.body;
res.status(200).send({
album: params
});
}
function updateAlbum(req, res){
var params = req.body;
res.status(200).send({
album: params
});
}
function deleteAlbum(req, res){
var id = req.params.id;
res.status(200).send({
data: id,
});
}
module.exports = {
getAlbum,
getAlbums,
saveAlbum,
updateAlbum,
deleteAlbum
}

view raw

album.js

hosted with ❤ by GitHub

Fíjate en la estructura y no en el código, de hecho hace mas bien poco o nada.

Este es sería un controlador típico en un modelo de CRUD en el que implementamos las cuatro operaciones típicas, lectura de datos, creación, actualización de datos y borrado.

Cada función de este controlador hará una tarea diferente por lo que decimos que serán funciones atómicas.

Peeeeero lo importante de toda esta película esta al final del script. Fíjate que al igual que hacíamos en el fichero app.js, en este estamos exportando las funciones que nos interesan para que puedan ser llamadas desde otro fichero, como por ejemplo desde el fichero de definición de rutas.

pERO CUANTAS RUTAS TIENE ESTE TIO???

Ha llegado el momento de definir las rutas de nuestra aplicación.

Y al igual que en el fichero anterior habíamos creado cuatro funciones (bueno en realidad 5 pero dos de ellas internamente sirven para lo mismo, getAlbum y getAlbums, lectura de datos) ahora vamos a crear también 4 rutas y cada una de ellas matcheará con un método HTTP diferente.

Para que no te pierdas este va a ser el esquema de la relación métodos HTTP (API Restful) y funciones:

  • Método GET -> getAlbum() y getAlbums()
  • Método POST -> saveAlbum()
  • Método PUT -> updateAlbum()
  • Método DELETE -> delteAlbum()

Lo mas importante y lo primero de todo es crear el fichero album.js en el directorio de /routes.


'use strict'
var express = require('express');
var AlbumController = require('../controllers/album');
var api = express.Router();
api.get('/album/:id', AlbumController.getAlbum);
api.get('/album', AlbumController.getAlbums);
api.post('/album', AlbumController.saveAlbum);
api.put('/album', AlbumController.updateAlbum);
api.delete('/album/:id', AlbumController.deleteAlbum);
module.exports = api;

view raw

album.js

hosted with ❤ by GitHub

Mira bien:

  • Línea número 3: cargamos el framework express.
  • Línea número 4: cargamos el controlador de álbum.
  • Línea numero 5: nos traemos el sistema para definir rutas del framework.
  • Línea 7: definimos una ruta GET para la función getAlbum().
  • Línea 8: definimos una ruta GET para la función getAlbums().
  • Línea 9: definimos una ruta POST para la función saveAlbum().
  • Línea 10: definimos una ruta PUT para la función updateAlbum().
  • Línea 11: definimos una ruta DELET para la función deleteAlbum().

Y con esto ya tendríamos la estructura básica y el artículo montado sobre como organizar un proyecto Node.js.

Por supuesto que faltan muchas cosas, de primeras el modelo de datos (eso lo dejaré para cuando empecemos con MongoDB) pero podríamos meter un directorio para la realización de test unitarios, otro para las vistas en caso en que quisiéramos ampliar la API… otro para utilidades, no sé…

El patrón MVC mínimo sería este, a partir de aquí tu ya Feel Free

Y nada, si tenéis algún tipo de preguntas no dudéis en hacérmelas llegar en los comentarios o a través del siguiente banner de Twitter.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

Hala a cascarla!

Herencia en la programación orientada a objetos

Que pasa churritas!

Ya estamos a puntito de terminar los artículos dedicados al «curso»… si curso… sobre programación orientada a objetos y si has seguido todos y cada uno de los posts ya serás capaz de entender los conceptos de la programación y de desarrollar un programa to’ flama. En el artículo de hoy vamos a volver a ver la herencia.

Es verdad que ya hable de ella y bastante bien por cierto en este primer artículo pero como en este post estaba rankeando por otra palabara clave pues toca marcarme la del partner y hacer un artículo en el que la palabra clave sea la herencia. Yeah bitches!

Así que vamos a ellos!

¿Qué coño es la herencia?

Es la primera pregunta obligatoria que te tiene que pasar por la cabeza y no hace referencia a la dota que te deja la bruja de tu tía cuando muere.

La herencia en la programación orientada a objetos hace referencia a la habilidad que tiene una clase para derivarse de otra clase. Cuando digo derivarse quiero volver a decir herencia pero es que no veas lo que me esta costando explicar este concepto que con su nombre ya lo dice todo…

Tenemos una clase, a la que típicamente se le conoce como clase base o clase padre. Esta clase tiene sus propiedades, sus métodos y sus constantes ¿no? Pues justamente podemos hacer que otra clase diferente tenga acceso a esas propiedades, métodos y constantes haciéndolos suyos y sin tener que volver a escribirlos en esta nueva clase.

Es esta la gracia de la herencia y de un sistema basado en la jerarquía. Podemos organizar nuestro código para que unas clases cuelguen de otras pero que a su vez puedan utilizar los métodos de las clases superiores, ahí está la ventaja de la herencia, en poder reutilizar código ya existente.

Además si lo hacemos bien y a medida que vamos creando clases padres estaremos creando abstracción en la lógica de nuestro programa. ¿Y esto que significa? Pues que estaremos entendiendo cada vez mejor el problema que tratamos de solucionar y a su vez estaremos preparando el programa para enfrentarnos a nuevos requerimientos o problemas ya sean esperados o no.

Pasar de lo genérico a lo abstracto. Y esto siempre es mejor y ya 😛

Querer buscar la abstracción en tu programa no significa que nos pongamos a hacer clases padres y clases hijas a lo loco. Tiene que existir un sentido lógico o de lo contrario estaremos llenando de mierda el código.

Ese sentido lógico lo encontramos a preguntarnos si una clase «es un» de otra clase, es decir, ¿un bolígrafo es una herramienta de escritura? Si. ¿Y un lápiz? ¿Es también una herramienta de escritura? Pues también. Ahí hay herencia, ¿la veis? Pero.. ¿y una pelota es una herramienta de escritura? Pues hombre, podríamos untar la pelota en pintura y dar pelotazos en la pared hasta que salga alguna palabra pero por lo general no, no es una herramienta de escritura y por ende ahí no hay herencia.

Así pues mediante este ejemplo tendríamos una jerarquía en la que existiría una clase padre llamada HerramientaDeEscritura.class.php por ejemplo y dos clases hijas llamadas Bolígrafo.class.php y Lapiz.class.php. Estas dos últimas clases van a compartir ciertas propiedades y ciertos métodos que vienen directamente heredados de la clase padre, aunque hay que aclarar que es puede que nos encontremos con métodos o propiedades que no pueden ser heredados ya que aquí entra en juego la visibilidad y el acceso. Si te perdiste esa parte te dejo aquí el enlace para que le eches un vistazo 😉

¿Qué gano si aplico herencia?

¿Que qué ganas al hacer herencia? Pues muchas cosas, aunque ya he mencionado una arriba y posiblemente sea de las mas importantes. Entender mejor el problema que tratamos de solucionar. Y esto sirve para hacerte el chulo porque si eres el único que entiende el problema y tus compañeros te preguntan tu jefazo tendrá una mejor visión de ti.

Hago herencia pa haserme el shulo
Hago herencia pa haserme el shulo

Pero fuera de todo esto a nivel de código el utilizar herencia tiene bastantes ventajas:

  • Si no somos unos paquetes conseguiremos reutilizar el código de forma eficiente. Write Once Run Anywhere, mas o menos. Escribes un método en una clase padre y lo utilizas en todas las clases hijas que te de la gana. El cenit de la vaguería…
  • Propagación de los cambios. Si quieres cambiar el valor de una constante, lo cambias en la clase padre y se aplica en todas las clases heredadas, pero ten cuidado porque las cagadas también se propagan!
  • Poder heredar propiedades y métodos de todas las clases superiores. Hacer una mega clase con toooodo lo anterior incluido, hasta el infinito y mas allá. No sería raro llegar a encontrarnos una clase hija que pinte de la siguiente forma:

https://gist.github.com/gorkamu/f451e5d678c1b689363141fbffc4ddf4.js
Clase hija que tiene mucha herencia y que no hace nada.

Pero en PHP la herencia es una putada porque solo tenemos disponible la herencia simple. A diferencia de otros lenguajes como por ejemplo con Java que una clase hija puede heredar de tantas clases padres como les de la gana, PHP únicamente puede heredar de una sola clase padre. Por supuesto esto evita la complejidad del programa pero también es verdad que se pierden muchas características del polimorfismo y por supuesto se pierde un poquito el dinamismo en tiempo de ejecución.

Pero bueno, hay que sacrificar unas cosas para ganar otras. Yo la verdad es que hubiera preferido que existiera herencia múltiple en PHP pero que le vamos a hacer…

Podría hablar de muchas otras cosas que influyen y ayudan en la herencia como por ejemplo los constructores y destructores, la visibilidad de los métodos y propiedades y la sobrescritura pero esos temas ya los he tocado en artículos anteriores así que te recomiendo que si no los has visto eches un vistazo a este link en el que aparecen todos los posts pasados.

Y si tienes dudas o quieres aportar alguna sugerencia pues lo dejas en los comentarios y yo ya responderé cuando tal y sino puedes utilizar twitter a través del siguiente banner que en el fondo siempre es mas directo.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

Hala a chuparla!

Enlace estático en tiempo de ejecución en la programación orientada a objetos

Pues ya hemos llegado al final de los artículos dedicados a la programación orientada a objetos. A estas alturas ya comprenderás todos los conceptos de este tipo de programación. Obviamente me he dejado muchas cosas en el tintero pero siempre he intentado explicar las diferentes partes con un poquito de humor y con ejemplos fuera de los típicos que puedes encontrar por Internet. Para el último artículo he querido dejar la explicación sobre como crear un enlace directo a una pagina web estático en tiempo de ejecución y es de lo que vamos a hablar, así que… let’s go madafakas!

Entendiendo el enlace estático en tiempo de ejecución

Para ser sinceros desconozco si otros lenguajes de programación implementan esta funcionalidad. Desde hace años mi carrera laboral ha ido por PHP en general y en los últimos años por Symfony en particular así que no estoy seguro, pero para el que no lo sepa, PHP incorporó la funcionalidad a partir de la versión 5.3 ea!

Básicamente el enlace en tiempo de ejecución consiste en poder hacer referencias a la clase en uso desde un contexto de herencia estática.

Da fuq?

WTF? Si la frase anterior te ha dejado con el culo torcido te recomiendo que le eches un vistazo a los links en los que hablo de herencia y sobre clases y métodos estáticos. Están un poquito atrás en el tiempo, tal vez un par de semanas pero por si acaso te has despertado con el vago puesto te dejo este y este link. De nada 😉

Antes de que metieran el enlace estático en tiempo de ejecución había problemas con la herencia y los métodos estáticos. Es decir, si una clase padre definía un método estático toda clase hija que heredase de esa clase obviamente iba a heredar ese método mágico pero cuando el motor de PHP intentaba resolver la palabra reservada self:: daba un pete porque la palabra reservada hacía referencia a la clase en la que se definía el método estático y no a las clases heredadas, con el ejemplo se va a ver mejor…
https://gist.github.com/gorkamu/c952a7a86a51e8123531b1844513eec3.js
Eso era antes claro y por lo tanto los desarrolladores nos sacamos de la manga un par de soluciones para resolver el problema:

  • Copiar y pegar los métodos estáticos de las clases padre en todas las clases hijas. Toma eficiencia claro que sí…
  • Convertir los métodos estáticos a métodos dinámicos. Toma parche claro que si…

Cuando el señor PHP se dio cuenta de este ‘error’ decidió implementar el enlace estático en tiempo de ejecución y para ello pensó en añadir una nueva palabra reservada pero viendo la realidad se decidió a utilizar otra técnica que ya tenemos bastantes palabras reservadas y meter una mas sería un follón.

Por eso la solución a toda esta película que os estoy contando fue ampliar el significado lógico de la palabra reservada static.

Si estas programando en PHP ya a partir de la versión 5.3 y con el enlace estático en tiempo de ejecución a tope de power, la palabra static permite obtener el valor de la clase desde donde se esta ejecutando en lugar de la clase base de la que hereda. Es como si la palabra reservada static se centrara y supiera donde se encuentra.

Así pues como vais a ver en el siguiente ejemplo, ya somo capaces de hacer referencia a la propia clase que ejecuta un método estático o accede a una propiedad estática sin tener que hacer malabares. Yeeaaah!! 😀
https://gist.github.com/gorkamu/f56a8d82a5ac4515eedc3978ae631d77.js

Y esto es todo muchachos, se acabó el último post sobre programación orientada a objetos. Ahora yo voy a descansar, que me metido un currazo en escribir todo el ‘curso’ y me voy a disfrutar de mis dolars ganados a las montañas del Pirineo junto a un par de buenas bitches.

Si tenéis dudas o sugerencias o simplemente queréis llorarme pidiendo que escriba algún curso nuevo hacédmelo saber en los comentarios o a través de twitter mediante el siguiente banner.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

A mamarla!

 

Rondita caliente de BLs:

http://www.folkd.com/user/comoycreo

https://my.originlab.com/forum/topic.asp?whichpage=1&TOPIC_ID=45555&#64955

https://my.originlab.com/forum/topic.asp?whichpage=1&TOPIC_ID=9589&#64956

https://my.originlab.com/forum/topic.asp?whichpage=1&TOPIC_ID=21723&#64957

https://my.originlab.com/forum/topic.asp?whichpage=1&TOPIC_ID=10692&#64958

https://www.intensedebate.com/people/comocrear

https://serato.com/forum/discussion/1364569#new

 

Sobrecarga en la programación orientada a objetos

Hoy dentro del ciclo de artículos sobre programación orientada a objetos vamos a ver otro concepto tan importante como la herencia o la sobrescritura de métodos. Hablo de la sobrecarga de métodos que en líneas generales se trata de re-definir el comportamiento de ciertos métodos para adaptarlos a tus necesidades.

Basta ya de introducciones y demosle ya chicha!

¿Qué es la sobrecarga?

Antes de explicarte a mi manera qué es la sobrecarga y poner un par de ejemplos vamos a ver cuál es la definición mas precisa que podemos encontrar en internet sobre el concepto. Según la definición de la wikipedia:

Sobrecarga es la capacidad de un lenguaje de programación, que permite nombrar con el mismo identificador diferentes variables u operaciones.

En programación orientada a objetos la sobrecarga se refiere a la posibilidad de tener dos o más funciones con el mismo nombre pero funcionalidad diferente. Es decir, dos o más funciones con el mismo nombre realizan acciones diferentes. El compilador usará una u otra dependiendo de los parámetros usados. A esto se llama también sobrecarga de funciones.

Bien, como dice el párrafo de arriba, es la posibilidad de tener varios métodos con el mismo nombre pero diferenciados entre ellos por el número de argumentos pasados, pero también es la posibilidad de alterar el comportamiento de otros tipos de métodos o propiedades.

Haz click aquí

Por ejemplo, si vienes del mundo de Java esto lo habrás visto ya muchísimo y si vienes del mundo de C/C++ te sonará la sobrecarga de operadores, cosa que me flipa muchísimo pero que por desgracia todavía no ha llegado a PHP.

A lo mejor te cuesta visualizar qué es el concepto de sobrecarga como para encima hablar de sobrecargar operadores pero es que el concepto es tan chulo que tengo que explicarlo.

Imagínate una suma de dos valores. Cada valor se encuentra entre un operador numérico ¿no? En este caso el operador es el símbolo de la suma (+) pero en otras operaciones el operador será otro obviamente. Pues bien, con C/C++ puedes hacer que cuando aparezca el operador de la suma se imprima un mensaje por consola y en lugar de hacer la suma, internamente se produzca una resta, por ejemplo.

Es el maximun trolling de la programación jejeje.

Como decía esto todavía no lo tenemos en PHP pero lo que si que tenemos y podemos utilizar desde ya es la sobrecarga de métodos.

Sobrecargando métodos en PHP

La sobrecarga en PHP nos ofrece herramientas para crear de una forma dinámica métodos y propiedades que después serán procesadas mediante alguno de los métodos mágicos que ya vimos en este artículo.

Básicamente el concepto va a ser el mismo en todos los lenguajes de programación pero PHP incluye la restricción de que no podemos tener varios métodos con el mismo nombre. Cada lenguaje tiene sus cosicas al igual que C/C++ tiene sobrecarga de operadores y Java no…

Cuando vamos a realizar sobrecarga de métodos en PHP nos tenemos que asegurar que aquellos métodos que queremos sobrecargar han de ser declarados como públicos y jamás de los jamases pasarle argumentos de estos métodos mágicos por referencia o de lo contrario hará un BUM Headshoot!

Para hacer esto se utilizan dos métodos mágicos en concreto:

  • __call(): se lanza cuando se invoca un método inaccesible desde un objeto.
  • __callStatic(): se lanza cuando se invoca un método estático inaccesible desde un objeto.

Ambos métodos mágicos van a recibir dos parámetros por narices, el primero de ellos corresponde al nombre del método que queremos sobrecargar y el segundo argumento es un array con los parámetros que pueda llegar a aceptar el método sobrecargado.
https://gist.github.com/gorkamu/f6c60c96029c7fbf81c1b2635de39c90.js
Decía antes que en PHP no existe la sobrecarga de métodos como se entiende en otros lenguajes, pues bueno, no es del todo así ya que como veis en el ejemplo se puede simular de cierta manera contando el número de argumentos que le llegan al método mágico __call() para después invocar una función u otra en función de esos argumentos.

Te recomiendo que te pilles el script, lo ejecutes y juegues con el para entenderlo bien 😉

Sobrecargando propiedades

Bien, toca el siguiente paso, aprender a sobrecargar las propiedades de una clase. Si con la sobrecarga de métodos utilizábamos los métodos mágicos __call() y __callStatic() con la sobrecarga de propiedades se utilizan los siguientes métodos mágicos:

  • __set(): se invoca cuando se escriben valores sobre propiedades inaccesibles.
  • __get(): se invoca cuando se consultan valores de propiedades inaccesibles.
  • __isset(): se invoca cuando se ejecutan los métodos isset() o empty() sobre propiedades inaccesibles.
  • __unset(): se invoca cuando se llama a unset() sobre propiedades inaccesibles.

Todos estos métodos mágicos van a esperar recibir un parámetro que represente el nombre de la propiedad sobre la que se quiere actuar pero, en el caso del método __set() recibe dos argumentos, uno con el nombre de la propiedad y otro con el valor que ha de asignarse.

Si declaras una propiedad como estática y después intentas sobrecargarla te pasará como con los métodos no públicos sobrecargados que también recibirás un bonito y elegante pete 😉
https://gist.github.com/gorkamu/8f3a9a320dcee5bfb9f83a5c4498dd96.js
Como perro que soy y rigiéndome siempre por la ley del mínimo esfuerzo este último ejemplo es el mismo que aparece en la documentación oficial de PHP pero eso no quita para que si tenéis dudas o queréis mas ejemplos me lo hagáis saber a través de los comentarios o por twittah mediante el siguiente banner.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

Es importante que os bajéis los ejemplos del cada artículo del repositorio habilitado para ello y que probéis y juguéis con los scripts para que entendáis bien los diferentes conceptos…

Hala a cascarla!

Funciones anónimas en la programación orientada a objetos

Ya queda poquito para terminar con la serie de artículos del curso de programación orientada a objetos. Si has llegado hasta aquí sin desfallecer enhorabuena, tendrás ya una base solida para empezar a programar. Como queda poco es hora de ir metiendo la puntillita y contarte cosas que harán que tus scripts sean mas elaborados por eso hoy vamos a hablar de las funciones anónimas o closures.

¿Qué son las funciones anónimas?

Puedes llamarlas de diferentes formas y te vamos a entender igualmente. Desde funciones anónimas a clausuras o closures en el idioma de William Shakespeare pero todas estas formas hacen referencia a la habilidad de los lenguajes modernos para crear funciones sin un nombre definido.

Al no tener un nombre definido no vas a poder invocarlas todas las veces que te den la gana sino que su uso tradicionalmente ha sido utilizado para las llamadas de retorno o los conocidos callbacks aunque obviamente tienen muchos otros usos.

Ponte en la situación de que creas una conexión a una base de datos y que después de realizar cualquiera de las acciones típicas del CRUD quieres que automáticamente escriba en un fichero de log lo que acabas de hacer. Pues esa función de retorno después de atacar la base de datos la podrías montar perfectamente con una función anónima, por ejemplo…

Es importante conocer que el motor de PHP internamente convierte este tipo de expresiones a instancias de la clase Closure.

Pero no solo podemos utilizar las funciones anónimas como callbacks sino que también las podemos asignar a variables. Si, la función entera, no solo el valor devuelto mediante un return desde la función. Así cuando el motor del lenguaje encuentre una referencia a esa variable ejecutará automáticamente la función anónima.

Se podría decir que es como darle un alias a la función pero no para que me entiendas…
https://gist.github.com/gorkamu/ba7dda22ffcd8d4703561f97744db9ca.js
En este ejemplo se ve perfectamente lo que acabo de explicar de asignar funciones anónimas a las variables. Pero no nos quedamos solo ahí ya que las closures de vez en cuando cuando le sale de los huevos al desarrollador pueden heredar variables del ámbito padre para ser utilizadas dentro de las mismas.

Me explico, si defines una variable de tipo string con un mensaje y a continuación defines una función anónima, puedes pasarle como argumento la variable a la clausura, ya sea por referencia o por valor. Pero que no te confunda, que tu función herede variables del ámbito padre no es lo mismo que hacer uso de variables globales. Todo tiene que ver que con el scope.

Eso si, si vas a hacer que tus funciones anónimas hereden variables acuérdate de de utilizar la palabra reservada use o de lo contrario recibirás un bonito y elegante pete 😉
https://gist.github.com/gorkamu/42e54f569b26e5639e437e08c94e0d53.js
Es posible que no todavía no veas la diferencia entre heredar variables del ámbito padre y usar variables globales aunque realmente creo que por su nombre es fácil de entender.

En cualquier caso, usar una variable global implica que da igual desde dónde la uses, ya sea desde dentro de una función, el método de una clase o desde otro fichero que forme parte de la arquitectura de tu programa.

Por el contrario el ámbito padre de las funciones anónimas es la función en la que la closure fue declarada que no es necesariamente la función desde la que se le invocó.

Pero hay más porque lo mismo que pasa con las funciones «normales», el lenguaje también nos permite crear funciones anónimas estáticas y que cuando las definimos en el contexto de una clase nos permite evitar que automáticamente la clase se vincule a la función. Es como romper el nexo de unión con la clase.

Lo malo de esta técnica es que al no estar la clase vinculada con la función anónima no podremos usar la palabra reservada $this para hacer referencia a la propia clase.
https://gist.github.com/gorkamu/1202dca9dae5dde8d5ba0fec560bca22.js
Ahora la decisión y el uso o no de funciones anónimas y funciones anónimas estáticas queda en tu mano. Por supuesto has de encontrar una finalidad justificada para usarlas ya que no es plan de que metas clausuras a muerte en todos tus scripts por que eso disminuye la optimización de tu código. Cuando compila el motor le asigna un nombre interno a esa función, si no es anónima y ya posee nombre le estarás quitando trabajo al compilador 😉

Pues nada chavales, a dejarme la dudas, peticiones y sugerencias en los comentarios o a través de twitter mediante el siguiente banner.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

Hala a cascarla!

#3 Plataforma como Servicio: Heroku vs Amazon Web Services

No te equivoques,  Amazon Web Services, AWS de ahora en adelante, y Heroku, no son dos plataformas como servicio, solo una de ellos pero ambas nos van a permitir implementar, supervisar y escalar aplicaciones web y móviles de manera completamente diferente. Pero antes de seguir hablando vamos a recopilar un poquito de información.

¿Que coño significa Plataforma como Servicio?

Según la Wikipedia una plataforma como servicio o PaaS es lo siguiente:

Es una categoría de servicios en la nube que permiten a los clientes desarrollar, ejecutar y manejar aplicaciones sin la complejidad de construir y mantener la infraestructura típica asociada con el desarrollo y lanzamiento de la aplicación.

Vamos que es tener, en cierto sentido, a un DevOps, o chico de sistemas, en tu equipo. Aunque algo mejor ya que no vas a tener que tratar con otra persona y ni te vas a comer la cabeza averiguando que falla cuando se romper algo.

Delegas esas tarea o al chico de sistemas o a una plataforma como servicio. ¿Que quieres hacer una build y desplegar? Pues la haces y te olvidas de compatibilidades, de versiones y librerías que fallan.

Así de primeras suena muy bonito y actualmente en el mercado tenemos varias soluciones que nos cubra esta necesidad. Desde soltar los billeticos y contratar a alguien que se encargue de la infraestructura o utilizar uno de estos servicios.

Debido a su baje coste y su fácil gestión si estas montando una startup vas a elegir casi el 100% de veces una de las siguientes plataforma como servicio pero… ¿Cuál es mejor?

Heroku contra Amazon Web Services

Vale, si echas un vistazo a los productos y servicios que te ofrece Amazon Web Service posiblemente te de un tabardillo debido a la gran cantidad de palabras y cosas que no te suenan hay para elegir. Es normal que te pierdas.

Diferentes Productos AWS
Diferentes Productos AWS

AWS ofrece una amplia cantidad de productos en los que elegir por lo que es difícil hacer una buena elección si no sabes ni de que va todo esto ni que solución es la idónea para tus necesidades.

Y ni siquiera has comenzado a considerar Heroku!

Pero bueno, relaja las tetas, no te agobies que es normal que te sientas abrumado. Vayamos poco a poco para ver las diferencias entre estas dos Plataformas como Servicio.

¿Qué Plataforma como Servicio escoger para mi Startup?

Si buscamos una comparativa de Heroku y Amazon Web Services veremos un montón de artículos que hablan de los beneficios de uno y de otro. Pero, ¿es lógica esta comparación? Intentar cruzar estos dos productos no tiene mucho sentido por las razones que iremos viendo a continuación.

AWS Elastic Compute Cloud

El Elastic Compute Cloud, también conocido como EC2 es una infraestructura como servicio (lo sé, otro actor mas en los …como servicio) y es el buque insignia de los productos ofrecidos por Amazon.

Antes de que existieran estas herramientas cuando uno quería montar, mantener y gestionar todo lo que existe al rededor de una aplicación tenía que desarrollar la infraestructuras de servidores que soportase la aplicación en cuestión.

Pero, ¿qué pinta tiene una plataforma com servicio? Bueno pues en pocas palabras si trabajamos con una PaaS, vamos a tener que configurar y mantener los servidores virtualizados que ejecuten nuestra aplicación, vamos a tener que agregar instancias de bases de datos, elegir y configurar el sistema operativo y configurar un balanceador de carga para distribuir la carga a través de varios servidores de aplicaciones.

Además, debemos seleccionar la CPU y unas cantidades mínimas de memoria RAM y almacenamiento tales que satisfagan nuestras necesidades.

Ah! Y lo mas importante, tenemos que instalar un servidor de copias de seguridad por si hay algo que se va a la wea!

Elastic Compute Cloud nos proporciona sólo los «bloques de construcción». Nuestra tarea es seleccionar los mejores bloques para nuestra aplicación y gestionarlos activamente, no solo tener que configurarlos.

En muchas empresas de desarrollo es bastante habitual encontrarse con la figura del DevOps que en grandes rasgos es el encargado de aprovisionar las instancias de EC2, controlar el despliegue de las aplicaciones y orquestar la infraestructura de los servidores.

Algo así como el que se encarga de decidir cómo estos «bloques de construcción» van a interactuar entre sí.

Pero bueno, ahora pasemos a ver qué es lo que nos ofrece Heroku.

Diferencias entre plataforma como servicio e infraestructura como servicio
Diferencias entre plataforma como servicio e infraestructura como servicio

Heroku, aquella plataforma como servicio con nombre japonés

Heroku es también otra plataforma como servicio (PaaS) basada en Amazon Web Services pero es totalmente diferente a Elastic Cloud Compute (EC2)

Es de vital importancia saber diferenciar entre las soluciones basadas en Infraestructuras como Servicio (IaaS) y Plataformas como Servicio sobre todo cuando al considerar deployar y mantener nuestra aplicación en una de estos dos soluciones.

Heroku es mucho mas sencilla de usar que AWS, es quizá demasiado simple pero hay una buena razón para que esto sea así.

Esta plataforma nos equipa con un entorno de ejecución y un conjunto de servidores de aplicaciones ya preparados. Además, nos beneficiamos de una integración perfecta con varias herramientas de desarrollo, un sistema operativo preinstalado y servidores redundantes.

Con esto no tenemos que «perder tiempo» pensando en la infraestructura tal y como haríamos con AWS EC2, tan solo escogemos un plan de subscripción y lo cambiamos si nos quedamos cortos.

Heroku se encarga convenientemente de los detalles. Por lo tanto, podemos apuntar todos nuestros esfuerzos al desarrollo de la aplicación.

Sólo se necesita un desarrollador web o varios desarrolladores para crear una aplicación y enviarla a Heroku usando un control de versiones como GIT.

Toda la gestión del despliegue de la aplicación se realiza a través de la terminal.

Así pues comparar Heroku con AWS EC2 es como comparar una tostadora con un microondas. Ambas máquinas las usamos para calentar (y a veces tostar) pan, pero funcionan de manera completamente diferente.

Así pues tanto con Amazon Web Service EC2 como con Heroku vamos a alcanzar objetivos distintos peeeeeero hay algo de lo que todavía no te he hablado y se trata de otro producto de Amazon que funciona igual que una plataforma como servicio y es el competidor directo de Heroku.

SERVICIOS AMAZON WEB SERVICE HEROKU
Ofrecido por Amazon Salesforce
Precio Pagas por lo que usas Pagas por lo que usas
Qué te ofrece Plataforma como Servicio (Elastic Beanstalk) e Infraestructura como Servicio (AWS EC2) Plataforma como Servicio
Concepto Plataforma lista para el deploy (Elastic Beanstalk) e infraestructura (AWS EC2) Plataforma lista para el deploy
Lenguajes soportados Ruby, NodeJS, Python, Go, Docker, PHP y .NET Ruby, Python, PHP, Clojure, Go, Java, Scala y Node.js
Capacidad de escalar Escalado automático en EC2 y Elastic Beanstalk basado en tiempos y métricas aunque puedes configurar el autoescalado antes de deployar Escalado manual a través de la terminal o del panel de administración
Disponibilidad geográfica En todo el mundo Estados Unidos y Europa
Características principales Aprovisionamiento, Balanceador de carga, Autoescalado, Monitor basado en métricas, múltiples configuraciones y plantillas de despliegue Aprovisionamiento, Rollback de base de datos y de aplicación, Escalado vertical y horizontal manual, Integración completa con Github y Monitor basado en métricas
Herramientas integradas Consola de administración, Terminal y AWS CloudWatch Heroku Command Line, Heroku Application Metrics, Heroku Connect, Heroku Status

Elastic Beanstalk, un nuevo jugador se unió a la partida

Si decíamos que usar AWS era complejo para hacer un deploy mientras que con Heroku no tanto, este nuevo producto de Amazon simplifica la manera en la que desplegamos nuestras aplicaciones en AWS.

Con AWS Elastic Beanstalk vamos a ser capaces de deployar la aplicación ejecutando comandos en una terminal proporcionada por AWS o utilizando la consola de administración y sin tener que preocuparnos de la gestión de la infraestructura, ya que de ello se ocupa Elastic Beanstalk.

Por lo general, no es necesario que configuremos el aprovisionamiento, el balanceador de carga o el escalado, aunque con esta herramienta es posible obtener acceso a la infraestructura si lo necesitamos.

También vamos a poder guardar múltiples opciones de configuración para nuestra aplicación y cargarlas cuando el entorno cambie a golpe de ratón.

Elastic Beanstalk utiliza instancias de EC2 para alojar su aplicación, por lo que la migración de AWS Beanstalk a EC2 es mucho fácil y eso es la leche.

Conclusión

Cuando te planteas escoger una de estar plataformas como servicio lo primero que tienes que considerar es el coste. ¿Qué es lo que mas va a costarte? ¿Manejar y gestionar la infraestructura por ti mismo o abstraerte de todo eso aunque el precio suba un poquito mas?

Así pues y a modo de resumen deberías usar AWS EC2 cuando:

  • Necesitas flexibilidad en la infraestructura para hacer el primer deploy de la aplicación
  • Tienes a mano a un (o unos) DevOps que te gestionen la infraestructura.
  • Si deployas constantemente nuevas versiones de tu aplicación
  • Tu aplicación exige grandes cantidades de recursos.

Y usar una solución basada en Plataforma como Servicio cuando:

  • Necesitas deployar lo que se conoce como MVP (Producto Mínimo Viable)
  • Necesitas mejorar la aplicación rápidamente después del feedback de los usuarios.
  • No puedes pagar a DevOps.
  • Tu aplicación no chupa tantos recursos.

Así pues, si estas montando una startup te recomiendo que tires hacia el camino de Heroku, aunque no es la única solución en el mercado de las plataformas como servicio pero si decides por alguna razón utilizar Amazon Web Service Elastic Cloud Compute asegúrate de que tienes a un buen DevOps porque si no vas a llorar como si fueras un chiquillo de 3 años 😛

Y nada, eso es todo. ¿Tu con cuál te quedas? ¿Has utilizado alguna vez una de estas herramientas? Si es así no dudes en dejarlo en los comentarios y si tienes alguna pregunta que sepas que puedes hacérmela usando twitter a través del siguiente banner.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

Hala a cascarla!

Incluir publicidad en una aplicación Ionic

Así es majos, este post es para enseñaros a empezar a monetiza tu nueva aplicación. Si has leído artículos viejos míos quizá ya sabrás a hacer una app con Ionic, habrás aprendido a meter un vídeo de Youtube en tu aplicación y tal vez hayas visto mis casos de éxito como este o este. Pues el siguiente paso es darse de alta en una red de anuncios, incluir publicidad en una aplicación y empezar a ganar pasta bitches.

Haciendo negocios con Admob

Lo primero que tenemos que hacer de todo es registrarnos en Admob. Admob es una empresa de «Mobile Advertising» por lo que si queremos ganar dinerico tenemos que enseñar anuncios en nuestra aplicación y esta empresa tiene muchos anuncios para enseñar, ah y es de Google jeje.

Nos venimos a esta url y realizamos el proceso de inscripción. Una vez que hayas terminado verás el panel de control en el que gestionarás tus bloques de anuncios y campañas.

Panel de control de Admob con el que podremos incluir publicidad en una aplicación
Panel de control de Admob con el que podremos incluir publicidad en una aplicación

Para poder incluir publicidad en una aplicación tendremos que conseguir un Ad unit ID, que es el código que identifica nuestra aplicación contra el sistema de anuncios. Para ello hay que hacer click en el botón:

Botón para añadir una nueva aplicación
Botón para añadir una nueva aplicación

Si tu aplicación no esta publicada ya en las tiendas oficiales te tocará hacerlo manualmente. Para ello hay que rellenar un formulario en el que se nos pide el nombre de la aplicación y la plataforma objetivo.

Registrando mi nueva app
Registrando mi nueva app

Una vez pases por las diferentes opciones para configurar el bloque de anuncios y ver la configuración opcional de analítica llega la parte de la implementación en el código de tu aplicación. Pero antes no te olvides de apuntar el código ca-pub, es el que se utilizará en la aplicación y aparece durante el proceso de creación del bloque de anuncios. Tiene una pinta tal que así:

Código con el que ganaremos dinerico
Código con el que ganaremos dinerico

Configuración necesaria para incluir publicidad en una aplicación

Si quieres incluir publicidad en una aplicación vas a tener que ensuciarte, meterte en código así que voy a ir picadito.

  • Abres la terminal (o consola) y te vas a la raíz de tu proyecto.
  • Te instalas el plugin cordova-plugin-admob escribiendo el siguiente comando y dejas que termine el proceso
cordova plugin add com.rjfun.cordova.plugin.admob
  • Si te quedas mas tranquilo puedes revisar los plugins instalados con el siguiente comando.
cordova plugin list
  • Añade el siguiente código a la función .run en el fichero app.js que lo encontrarás dentro del directorio www. También tienes una versión separada del script.
.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    if(window.cordova &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; window.cordova.plugins.Keyboard) {  
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
      cordova.plugins.Keyboard.disableScroll(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }
    if (window.device &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; typeof AdMob !== "undefined") {
          var admob_key = ca_app_pub_code = "AQUI_TU_CODIGO_CA_PUB";

          AdMob.createBanner( {
            adId: admob_key,
            position: AdMob.AD_POSITION.BOTTOM_CENTER,
            isTesting: false,
            adSize: 'SMART_BANNER',
            success: function(){
            },
            error: function(){
              console.log('failed to create banner');
            }
          });
      }
  });
})

Obviamente tienes que cambiar el valor de la variable admob_key, donde pone «AQUI_TU_CODIGO_CA_PUB» tienes que sustituirlo por tu código, el que has generado un poco mas arriba al registrar la aplicación en Admob.

Y eso es todo chicos. bueno, no del todo. Mientras estes haciendo pruebas en tu entorno puedes activar la variable isTesting, es un booleano así que sus valores son true o false. Esto sirve para enseñar un anuncio de prueba antes de ser enviado a las tiendas oficiales. No te olvides de dejarlo como false cuando compiles y vuelvas a enviar la app o sino no verás gallinicas 😛

Si tenéis alguna duda sobre cómo incluir publicidad en una aplicación o sobre cualquier otra cosa podéis dejarla en los comentarios o usar el banner de Twitter para preguntarme directamente. Venga gandules que es gratis.

[xyz-ips snippet=»FAQS-GORKAMU-TW-YELLOW»]

 

Hala a mamarla!