MongoDB , NodeJS y API REST

Desde que escribí el post acerca de twitter, de cómo las bases de datos NoSQL revolucionaron las webs con masivas cantidades de datos tenía más ganas de mostraros algunos ejemplos de uso de este tipo de base de datos no relacional, y de cómo podemos utilizarla en nuestro servidor aunque no lo traiga preinstalado.

MongoDB

He estado creando servidores para videojuegos con este motor de base de datos usando mi propio servidor Apache. Aquí tenéis las instrucciones de instalación de la web oficial.
Lo primero que necesitáis es instalarlo en vuestro servidor.
Si tenéis un un host dedicado es más fácil, sino podréis usarlo de otra manera con un truco.

Instalación
1) Descargar MongoDB para servidor GNU/Linux:

curl -O http://downloads.mongodb.org/linux/mongodb-linux-x86_64-2.6.3.tgz

o con wget también:

wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-2.6.3.tgz

del manual podréis sacar la última versión.

2) Descomprimir en el directorio-de-instalacion-de-mongodb:

tar -zxvf mongodb-linux-x86_64-2.6.3.tgz

3) Exportar el directorio de instalación de mongo para hacer el comando mongo accesible desde cualquier lugar

export PATH=directorio-de-instalacion-de-mongodb/bin:$PATH

4) Crear directorio para almacenar las bases de datos

mkdir directorio-de-instalacion-de-mongodb/data

No recomiendo usar núcleos de 32bits porque es más complicada la instalación y mongo da más problemas en cuanto a funcionamiento, pero todo es posible.

Arrancar y crear una base de datos MongoDB
Ahora que tenemos instalado MongoDB,y hemos creado un directorio para guardar las bases de datos, iremos a su directorio de ejecutables (bin) para que una vez iniciado por primera vez cree el espacio para almacenarlas, también podemos seguir el manual oficial para crear una base de datos de MongoDB:

1) Arrancar

directorio-de-instalacion-de-mongodb/bin/mongo --smallfiles --dbpath directorio-de-instalacion-de-mongodb/data > /dev/null &

La opción smallfiles es para que cree ficheros de journal pequeños, si no la usáis, cada fichero journal tendrá inmediatamente tras crearse (en 5 minutos aproximadamente), nada menos que 1GB cada uno, al usar la opción tendréis ficheros de 64MB a 128MB, lo cual es mucho mejor, con 2 bases de datos, y smallfiles el directorio data puede llegar a pesar unos 600MB aproximadamente. Avisados quedáis :D

2) Crear base de datos, primero lanzamos mongo:

cd directorio-de-instalacion-de-mongodb/bin
./mongo

por defecto intentará conectarse al localhost y el puerto 27017, podéis usar otro servidor y puerto como argumentos del comando mongo.
Para crear la base de datos usamos el comando, dentro de mongo: “use miBaseDeDatos”.
Ya está, sin commits, ni nada más, ahora simplemente podemos usarla desde fuera.

Operar con una base de datos MongoDB
Ya tenemos nuestro motor Mongo funcionando y una base de datos creada, para sacar o meter datos con ella desde la consola lo hacemos usando el comando:

directorio-de-instalacion-de-mongodb/bin/mongo --eval 'comando mongo'

y nos mostrará el resultado en pantalla.
Recordar que existe, igual que ocurre con MySQL y su PHPMyAdmin, un PHPMoAdmin, aquí la lista de software para operar con interfaces.

Si queremos operar con ella desde PHP:

  • Si tienes instalada la extensión de Apache para PHP de Mongo podéis usar directamente la clase MongoClient para operar con las bases de datos de vuestro servidor. Ejemplo de conexión:
    $conexion = new MongoClient(); // conectar a localhost:27017
    // conectar a un host remoto (puerto predeterminado: 27017)
    $conexion = new MongoClient( "mongodb://example.com" ); 
    // conectar a un host remoto en un puerto dado
    $conexion = new MongoClient( "mongodb://example.com:65432" );
  • Si no te es posible acceder a la clase MongoClient es posible que tu Apache no disponga de la extensión de MongoDB de PHP, por lo que tienes que inventar un truco, a mí se me ocurrió, usar directamente el comando mongo como hemos visto antes, hay una instrucción de este comando que es “shellPrint“, con ella podemos obtener el resultado de un comando como texto, que podemos convertir en JSON para PHP con el comando json_decode, así, para ejecutar un comando MongoDB y recibir una respuesta JSON nos bastaría con hacer esto en PhP:
    //donde guardar el resultado de la consulta
     $home = "directorio_temporal/";
    //para guardar el resultado (nombre único) 
     $file = "resul".time().".txt"; 
     $query= 'shellPrint(
     db.miBaseDeDatos.insert(TU_CADENA_DE_DATOS_JSON)
     )';
     //lanzar comando mongo:
     exec('directorio-de-instalacion-de-mongodb/bin/mongo 
    --quiet localhost:27017/miBaseDeDatos --eval \''.$query.'\' >'.$home.$file);
    $result = file_get_contents($home.$file);
    @unlink($home.$file); //borrar resultado
    if (empty($result)) {
      //algo ha ido mal 
      $json= "{}";//cadena JSON VACIA
    } else {
      $json = str_replace(array("[","]","ObjectId("),"", $result);
      $json = str_replace('")','"',$json);
    }
    //crear el contenido JSON:
    $datos = json_decode($json);
    var_dump($datos);

Altas, bajas, modificaciones
Para insertar datos en mongo se usan collections, esto representarían nuestras tablas de SQL de siempre, salvo que todo son datos JSON, insertar una fila sería construir un array ,pasarlo a JSON y hacer un db.coleccion.insert(cadena_json), para buscar un dato, bastaría on usar find en lugar insert, los operadores se colocan dentro de un array de json, especificando primero qué campo debemos comparar, por ejemplo “$ne” es para no igual, $eq para igual, ejemplo:

 $query='shellPrint(db.letters.find(
    {
      username:{$ne:"'.$username. '"}, 
    scene:{$eq:'.intval($scene).'},'.
    'lang:{$eq:'.$lang.'}
    }
  ).toArray())';

este comando buscaría usuarios que no sean el usuario que pide la lista, ni desde el dispositivo que estén en la misma escena de juego que él (o ella xD) y cuyo lenguaje sea el mismo que usa, no olvidar pasar el comando a array con la función toArray del cliente de mongo, de forma que podamos luego convertirla en una cadena JSON y usar json_decode. También podemos usar cómodos arrays de datos y el comando json_encode para hacer la inserción de los mismos en la colección elegida de la base de datos.

Usar un servidor MongoDB externo
Si no podéis usar vuestro propio mongo en vuestro servidor, bien sea porque no tenéis acceso shell o no queréis sobrecargarlo, o cualquier otra cosa, podéis usar un servicio como MongoLab, tiene soporte para usar bases de datos NoSQL, en nube, etc. ,de los proveedores más grandes del mercado, como Google, Amazon o Microsoft. Pero trata los datos de forma transparente de forma que los usaremos como bases de datos mongodb.
Podemos acceder a ellas una vez creadas desde nuestro propio servidor, usando la extensión MongoDB Apache o bien usando el comando “mongo –host tuId.mongolab.com –port 63789 -u usuario -p password basededatos

En otro caso…

API REST

Una API REST es una aplicación web que nos permite mediante POST o GET mandar y obtener datos de un servidor, el intercambio se suele hacer en JSON o XML. Es común usar bloqueo y cifrado de conexiones, conexiones seguras ssl o por vpn, con llaves privadas y públicas, etc, ya que sus operaciones pueden resultar peligrosas.

En el caso de que nuestro servidor nos impida realizar conexiones de sockets externos, como sería ,el poder acceder a nuestra base de datos externa en mongolab, nos veríamos obligados a usar su REST API.

Esta es una manera de hacerlo:

$api = "https://api.mongolab.com/api/1/databases/miBaseDeDatos/%s?apiKey=MI_API_KEY";
$ch = curl_init();
$fields = json_encode(array('username'=>"juaxix"));
curl_setopt($ch, CURLOPT_URL, sprintf($api,"collections/usuarios/"));
curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, 
  array(
     "Content-Type: application/json; charset=utf-8",
     'Content-Length: ' . strlen($fields)
  )
 );
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookies.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookies.txt");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
echo curl_exec($ch);

También podemos realizar las operaciones de alta/baja/modificación usando AJAX:

 $server = "https://api.mongolab.com/api/1/databases/mi-db/".
           "collections/mi-coll?apiKey=miAPIKey";
//Insertar
$.ajax( { url: $server,
	data: JSON.stringify( { "x" : 1 } ),
        type: "POST",
        contentType: "application/json" } );
 //Modificar
 $.ajax( { url: $server.'&q={"_id":1234}',
	data: JSON.stringify( { "$set" : { "x" : 3 } } ),
	type: "PUT",
	contentType: "application/json" } );
//etc

Esta opción es la que uso ahora mismo con mis juegos online, he comprobado que un servidor de este tipo es más rápido que instalarlo en otro que dedica más tiempo de CPU a servir webs con Apache. Es decir, un server dedicado a mongo es mucho mejor, así, tendremos la posibilidad de atender millones de peticiones perfectamente.

Node.js

Si queremos tener un servidor de alta capacidad como Node.js, el cual además se usa para servidores de videojuegos también, seguir los pasos.
1) Para instalar Node.js vamos a su sección de descargas, y realizamos la misma operación que con la instalación de mongodb, descargar, descomprimir, instalar, lanzar, el problema de instarlo en vuestro propio servidor es que necesitaréis acceder a él o bien con un comando CGI o con PHP, de nuevo tenemos Apache como cuello de botella, lo mejor sería tener un servidor sólo con Node, lo bueno de este servidor es la facilidad con la que se pueden hacer aplicaciones en él y su rapidez + capacidad de manejar un gran volumen de usuarios, por otro lado ,las pruebas que estoy haciendo con litespeed (lshttpd) me están dejando muy sorprendido en cuanto a resultados de eficiencia.

Artículos relacionados:

  • No hay artículos relacionados

Please type the characters of this captcha image in the input box

Por favor escriba los caracteres de la imagen captcha en el cuadro de entrada

footer
jbelon © | sitemap.xml