Installing Atom and Vagrant/Homestead Box

Docker instead of Vagrant

LaraDock helps you run your Laravel App on Docker real quick. It’s like Laravel Homestead but for Docker instead of Vagrant.

LaraDock

Update Ubuntu (Elementary OS 14.04.1)

sudo apt-get update
sudo apt-get upgrade

Git

sudo apt-get install git

Atom Editor

sudo add-apt-repository ppa:webupd8team/atom
sudo apt-get update

sudo apt-get install atom

sudo apt-get upgrade

Latest Stable Node JS

curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -j nodejs

sudo apt-get install -y build-essential

NPM

npm config set prefix ~/.npm
vim ~/.bashrc

export PATH="$PATH:~/.npm/bin"

Linters

npm install -csslint
npm install -jshint

sudo apt-get install php5-cli
sudo apt-get install php-pear
sudo pear install PHP_CodeSniffer

Composer

curl -sS https://getcomposer.org/installer | php && sudo mv composer.phar

Vagrant

Manually download via URL and install latest Vagrant version.

Virtualbox

wget http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc

sudo apt-key add oracle_vbox.asc

sudo apt-get update

sudo apt-get install virtualbox-5.0
sudo apt-get install virtualbox-dkms

sudo apt-get upgrade

Composer

vim ~/.bashrc

export PATH="$PATH:~/.npm/bin:~/.composer/vendor/bin"
composer global require "laravel/homestead=~2.0"

mkdir ~/Code

homestead init
vim ~/.homestead/Homestead.yaml

sudo vim /etc/hosts
homestead up
homestead ssh

Atom Theme

seti-syntax
seti-ui

Atom Packages

angularjs
atom-autocomplete-php
atom-beautify
atom-material-syntax
atom-material-ui
atom-pair
atom-ternjs
autoclose-html
color-picker
docblockr
editorconfig
emmet
file-icons
git-time-machine
hyperclick
hyperclick-php
javascript-snippets
js-hyperclick
language-javascript-jsx
linter
linter-csslint
linter-jshint
linter-phpcs
merge-conflicts
minimap
pigments
plantuml-viewer
rest-client
sort-lines
terminal-plus

Integración Continua Agil como Práctica de Desarrollo

Rocketeer es agilidad con baterías, es moderno y además permite gestionar de manera fácil las tareas, los eventos y la gestión de implementaciones/lanzamientos de proyectos o aplicaciones. Es inspirado en la filosofía Laravel: Ser ágil, elegante y lo más importante, fácil de usar.

Por favor consulte:

Igual que Laravel, hace hincapié en el uso de valores predeterminados inteligentes presentes en el desarrollo de punta. Con Rocketter se puede implementar cualquier proyecto desde pequeños sitios web HTML/CSS hasta aplicaciones grandes realizadas con PHP, Rails, entre otros…”.

Send your projects up in the clouds

Ahora tengo muchas ganas de seguir explorando: Ansible, Crusible y Review Board.

Docker – Construir, armar y correr cualquier aplicación, en cualquier lugar

Docker sirve para construir, armar y correr cualquier aplicación, en cualquier lugar. Es una plataforma abierta para aplicaciones distribuidas para desarrolladores y administradores de sistemas.

“Docker Engine”

Es una herramienta de empaquetado portátil y ligera en tiempo de ejecución.

“Docker Hub”

Ofrece un servicio en la nube que permite compartir aplicaciones y automatización de flujos de trabajo. Docker permite ensamblar de manera agil componentes para aplicaciones, además busca eliminar la fricción entre los ambientes de desarrollo, control de calidad y de producción.

Administrando sistemas de manera agil

Como resultado, TI puede armar rápido y ejecutar la misma aplicación, sin cambios, en los ordenadores portátiles, los centros de datos de máquinas virtuales, y cualquier otra nube.

“Running a custom docker image”

LAMP: https://github.com/josoroma/lamp

docker

Yeoman el generador de andamios

Yeoman es la herramienta para generar el andamio de una aplicación Web moderna. Ofrece un ecosistema de generadores. Un generador es, básicamente, un plugin que se puede correr con el comando “yo” para producir el andamio de un proyecto.

Yeoman Workflow

Herramientas

El flujo de trabajo Yeoman se compone de tres herramientas fundamentales que impulsan la mejora de la productividad y la satisfacción en la construcción de una aplicación web:

  • yo – La herramienta de andamios de Yeoman.
  • bower – La herramienta de gestión de paquetes.
  • grunt – La herramienta de construcción.

Instalación

Vamos a empezar instalando Yeoman y el “Ionic Framework Generator“:

npm install -g yo bower gulp grunt-cli compass ios-sim generator-ionic
mkdir yoionic && cd $_

yo ionic yoionic
grunt —force
grunt platform:add:ios

grunt emulate:ios --force
grunt serve --force

Después de instalar Yosemite

Sobre Python

Como no voy a desarrollar en Python por el momento voy a optar por dejar la instalación de Python tal y como se encuentra, más que todo para evitar problemas con el sistema.

which python

/usr/bin/python
python --version

Python 2.7.6
python

Python 2.7.6 (default, Sep  9 2014, 15:04:36) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin

Sobre Bash

También voy a optar por dejar la instalación de Bash tal y como se encuentra:

which bash

/bin/bash
bash --version

GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin14)

bash-it

bash-it es un mashup varios comandos y scripts de bash, también incluye otras cosas interesantes en bash (Se inspira en oh-my-zsh :).

Permite configurar autocompletado, temas, alias, funciones personalizadas y más.

Más información: bash-it

cd

git clone https://github.com/revans/bash-it.git ~/.bash_it

Cloning into '/Users/God/.bash_it'…

Aliases

atom ~/.bash_it/aliases/custom.aliases.bash

Por ejemplo

cite 'about-alias'
about-alias 'josoroma'

alias updatedb='sudo /usr/libexec/locate.updatedb'

alias confhosts='sudo atom /etc/hosts'
alias confvhosts='sudo atom /etc/apache2/extra/httpd-vhosts.conf'
alias confapache='sudo atom /etc/apache2/httpd.conf'
alias confphp='atom /usr/local/etc/php/5.6/php.ini'
alias confmongo='atom /usr/local/etc/mongod.conf'

alias restartapache='sudo apachectl restart'
alias restartmysql='mysql.server restart'
alias restartsshagent='~/bin/ssh-agent'

alias www='cd /Library/WebServer/Documents'

alias gitcompare="git diff --stat master develop"

alias gitcompare1="git log --pretty=format:'%h' -2 master && git log --pretty=format:'%h' -2 develop"

alias gitcompare2="git log --pretty=format:'%h - %an, %ar : %s' -2 master && git log --pretty=format:'%h - %an, %ar : %s' -2 develop"

alias atompackages="ls -l ~/ .atom/packages | awk '{print $8}'"

alias aliases='atom ~/.bash_it/aliases/custom.aliases.bash'

Instalar PIP

Una herramienta para la instalación y gestión de paquetes de Python:

sudo easy_install pip

Installing pip script to /usr/local/bin
Installing pip2.7 script to /usr/local/bin
Installing pip2 script to /usr/local/bin

HTTPie

HTTPie es un cliente de línea de comandos HTTP. Su objetivo es hacer la interacción CLI con los servicios web tan fácil y humano como sea posible.

Proporciona un comando http que permite el envío de peticiones HTTP utilizando una sintaxis simple y natural, y muestra las respuestas coloreadas.

HTTPie se puede utilizar para la prueba, depuración y, en general para interactuar con servidores HTTP.

Más información: HTTPie

sudo easy_install httpie

Searching for httpie
Reading https://pypi.python.org/simple/httpie/
Best match: httpie 0.8.0

Installing http script to /usr/local/bin

Por ejemplo

http -v httpie.org

GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: httpie.org
User-Agent: HTTPie/0.8.0

HTTP/1.1 302 Found
Cache-Control: max-age=1800
Connection: Keep-Alive
Content-Length: 223
Content-Type: text/html; charset=iso-8859-1
Date: Sun, 30 Nov 2014 17:53:00 GMT
Expires: Sun, 30 Nov 2014 18:23:00 GMT
Keep-Alive: timeout=5, max=250
Location: https://github.com/jakubroztocil/httpie
Server: Apache
X-Awesome: Thanks for trying HTTPie :)

Instalar Xcode desde el App Store

Para construir aplicaciones para OS X de Yosemite, asegúrese de que ha instalado OS X Yosemite y Xcode. Actualmente es posible enviar aplicaciones de Mac escritas con Swift a la Mac App Store.

Xcode Command Line Tools

xcode-select -p
ls -la /Applications/Xcode.app/Contents/Developer

Homebrew

El gestor de paquetes de lo que le hizo falta a OS X. Instala esas “cosas” que necesitamos y que Apple no instaló.

Más información: brew.sh

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

This script will install:

/usr/local/bin/brew

Verificar el estado de Brew

brew doctor

Actualizar

brew update && brew upgrade `brew outdated`

Un flujo de trabajo que mediante CLI permite la administración de aplicaciones de Mac que son distribuidas en binario:

brew install caskroom/cask/brew-cask

El proyecto XQuartz es un esfuerzo para desorollar una versión “open source” X.Org del X Window System que corra en OS X:

brew cask install xquartz
brew help

brew –config

HOMEBREW_VERSION: 0.9.5
ORIGIN: https://github.com/Homebrew/homebrew
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CELLAR: /usr/local/Cellar
CPU: quad-core 64-bit haswell
OS X: 10.10.1-x86_64
Xcode: 6.1
CLT: 6.1.0.0.1.1413057044
Clang: 6.0 build 600
X11: N/A
System Ruby: 2.0.0-481
Perl: /usr/bin/perl
Python: /usr/bin/python
Ruby: /usr/bin/ruby

Network Tools

brew install wget mtr nmap iftop lynx fping arp-scan htop pgrep

Considere la posibilidad de establecer la siguiente ruta en PATH:

echo export PATH='/usr/local/sbin:$PATH' >> ~/.bash_profile

Image Magick

Para convertir, editar y componer imágenes.

Más información: Image Magick – Command line tools

brew install ImageMagick --with-ghostscript

ACK

Es una herramienta como grep pero optimizada para desarrolladores.

Más información: beyondgrep.com

brew install ack

MySQL

La Base de Datos de código abierto más popular del mundo:

brew install mysql
mysql.server restart
mysql_secure_installation
unset TMPDIR
mysql_install_db --verbose --user=`whoami` \\
--basedir="$(brew --prefix mysql)" \\
--datadir=/usr/local/var/mysql --tmpdir=/tmp
mysql.server restart
mysql -u root -p

Git

Potente herramienta para la colaboración, revisión y la gestión de código de proyectos.

brew install git

brew install node

Actualizar node:

npm install -g npm@latest
node --version

v0.10.33

SSH para Git

brew install ssh-copy-id
ssh-keygen -b 2048 -C "username@example.com" -f ~/.ssh/id_username_domain_rsa
ssh-add ~/.ssh/id_username_domain_rsa
ssh-add -l
git config --global user.name "username"
git config --global user.email "username@example.com"
git config --global push.default upstream
git config --global branch.autosetuprebase always
git config --global color.ui true
ssh-copy-id -i ~/.ssh/id_username_domain_rsa.pub username@remote.example.com

Aseguramiento de la calidad del código

npm install -g jshint

npm install -g csslint

Herramienta basada en nodejs que srive para optimizar archivos de gráficos vectoriales SVG:

npm install -g svgo

Sails

sudo npm install sails -g
brew install mongodb

Mongo

brew install mongodb

Para levantar Mongo al iniciar el sistema:

ln -sfv /usr/local/opt/mongodb/*.plist ~/Library/LaunchAgents

o para levantar el servicio Mongo en este el momento:

mongod --config /usr/local/etc/mongod.conf

Genghis

Una aplicación para la adminsitración de MongoDB.

Más información: GenghisApp.com

sudo gem install genghisapp
sudo gem install bson_ext -v 1.9.2
genghisapp --kill
genghisap

Antes de instalar PHP

brew tap homebrew/dupes

Cloning into '/usr/local/Library/Taps/homebrew/homebrew-dupes'...
brew tap homebrew/versions

Cloning into '/usr/local/Library/Taps/homebrew/homebrew-versions'...
brew tap homebrew/homebrew-php

Cloning into '/usr/local/Library/Taps/homebrew/homebrew-php'...

Instalar PHP

Más información: Homebrew PHP

brew install php56 php56-crypto php56-imagick php56-mcrypt php56-mongo php56-pspell php56-xdebug php56-oauth
 ./configure --prefix=/usr/local/Cellar/php56/5.6.3

 --localstatedir=/usr/local/var

 --sysconfdir=/usr/local/etc/php/5.6

 --with-config-file-path=/usr/local/etc

Para habilitar PHP en Apache hay que agregar la siguiente línea al httpd.conf y luego reiniciar Apache:

LoadModule php5_module    /usr/local/opt/php56/libexec/apache2/libphp5.so

php.ini

sudo atom /usr/local/etc/php/5.6/php.ini

Para levantar PHP al iniciar el sistema:

ln -sfv /usr/local/opt/php56/*.plist ~/Library/LaunchAgents

Para levantar PHP en este momento:

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.php56.plist

Apache

sudo apachectl configtest
sudo chown -R josoroma:staff /Library/WebServer/Documents
tail -f /private/var/log/apache2/error_log
ls -la /usr/local/etc/php/5.6/conf.d/
php -i

Composer

Gestor de dependencias para PHP.

Más información: Composer

brew install composer

Aseguramiento de la calidad del código PHP

Para detectar violaciones sobre las normas de codificación:

brew install php-code-sniffer php-cs-fixer

sudo atom /etc/apache2/httpd.conf

Descomentar los siguientes módulos

LoadModule include_module libexec/apache2/mod_include.so
LoadModule log_debug_module libexec/apache2/mod_log_debug.so
LoadModule session_module libexec/apache2/mod_session.so
LoadModule session_cookie_module libexec/apache2/mod_session_cookie.so
LoadModule session_dbd_module libexec/apache2/mod_session_dbd.so
LoadModule vhost_alias_module libexec/apache2/mod_vhost_alias.so
LoadModule rewrite_module libexec/apache2/mod_rewrite.so

Modificar la ubicación del módulo PHP5

LoadModule php5_module /usr/local/opt/php56/libexec/apache2/libphp5.so

Modificar en “unixd_module”

User josoroma
Group staff

Modificar “ServerAdmin” y “ServerName”

ServerAdmin username@example.com
ServerName 127.0.0.1

En Directory “/Library/WebServer/Documents” modificar

AllowOverride All

Permitir Virtual Hosts descomentando la siguiente línea

Include /private/etc/apache2/extra/httpd-vhosts.conf

Virtual Hosts

sudo atom /etc/apache2/extra/httpd-vhosts.conf
<VirtualHost *:80>
 DocumentRoot "/Library/WebServer/Documents/example.com/www/"
 ServerName example.com
 ErrorLog "/private/var/log/apache2/example.com_error_log"
 CustomLog "/private/var/log/apache2/example.com_access_log" common
</VirtualHost>

hosts

sudo atom /etc/hosts
127.0.0.1	localhost scorpion.local
127.0.0.1	example.com
#
255.255.255.255	broadcasthost
::1             localhost
sudo apachectl restart

REST API con Sails – Adaptadores y MongoDB

Información de prueba

curl -is -X POST -d "username=josoroma&email=josoroma@example.com" http://localhost:1337/user

curl -is -X POST -d "username=celine&email=celine@example.com" http://localhost:1337/user

curl -is -X POST -d "username=uifi&email=uifi@example.com" http://localhost:1337/user/create

curl -is -X POST -d "username=coco&email=coco@example.com" http://localhost:1337/user/create
curl -is -X GET http://localhost:1337/user

curl -is http://localhost:1337/user

Generar REST API de ubicación

cd places

sails generate api location

sails lift

Listar

curl -is http://localhost:1337/location

Obtener un Registro desde el Browser

http://localhost:1337/user?where={"username":{"contains":"josoroma"}}

Por favor consulte: Find

Instalar MongoDB

brew install mongodb
lsof -iTCP -sTCP:LISTEN | grep mongo

mongod    337 user   11u  IPv4 0xfbda8d570c57142b      0t0  TCP localhost:27017 (LISTEN)
ps aux | grep '[m]ongo'

user          337   0.0  0.4  2718292  34692   ??  S     2:21PM   0:18.24 /usr/local/opt/mongodb/bin/mongod --config /usr/local/etc/mongod.conf
cat /usr/local/etc/mongod.conf

systemLog:
  destination: file
  path: /usr/local/var/log/mongodb/mongo.log
  logAppend: true
storage:
  dbPath: /usr/local/var/mongodb
net:
  bindIp: 127.0.0.1

Por favor consulte: Install MongoDB on OS-X

Instalar el adaptador MongoDB para nuestra aplicación

cd places

npm install -g sails-mongo --save

sails-mongo asocia/mapea el atributo lógico id con el _id de la capa física del Mongo id. En la versión actual de sails-mongo, no se debe ordenar por id.

Por favor consulte: sails-mongo

config/connections.js

mongo: {
  adapter: 'sails-mongo',
  host: '127.0.0.1',
  port: 27017,
  user: '',
  password: '',
  database: 'places'
},

Por favor consulte: Default MongoDB Port

lsof -iTCP -sTCP:LISTEN | egrep ':2701[7..9]'

mongod    337 user   11u  IPv4 0xfbda8c570c57143b      0t0  TCP localhost:27017 (LISTEN)

config/models.js

// Sails-Mongo Connection.
connection: 'mongo',

// Development Mode.
migrate: 'drop'

Lift

cd places

sails lift

Mongo desde la consola

mongo

Listar las Bases de Datos:

show dbs

admin   (empty)
local   0.078GB
places  0.078GB

Usar la Base de Datos llamada places:

use places

switched to db places

Listar las colecciones de la Base de Datos places:

show collections

location
system.indexes
user

Listar todos los documentos de la colección user:

db.user.find().pretty();

Por favor consulte:

REST API con Sails – Apps y CRUD

Crear una nueva App

sails generate new {pluralApplicationName}

sails new places

cd places

atom

Correr la aplicación Sails

Correr la aplicación Sails desde el directorio actual (si el archivo node_modules/sails existe, se utiliza en lugar del Sails instalado globalmente).

sails lift

Por favor consulte: sails lift

sails new {pluralApplicationName} es un alias que corre sails generate new {pluralApplicationName}.

Generar REST API de Usuario

cd {pluralApplicationName}

cd places

sails generate api {singularRestApiName}

sails generate api user

sails lift

Comprobar que el REST-API responde bien

curl -s http://localhost:1337/user

[]

Genera:

  • api/models/User.js
  • api/controllers/UserController.js

Configurar config/models.js

Por favor consulte: Migrate

  • sails.config.models.migrate=”alter”
  • migrate: ‘alter’

Esta opción controla si Sails intentará automáticamente reconstruir las Tablas/Colecciones/Conjuntos/etc. en el esquema de la Base de Datos.

En producción (NODE_ENV === “production”)

Sails utiliza siempre migrate: ‘safe’ para proteger el borrado accidental de datos. Sin embargo, durante el desarrollo, existen otras opciones interesantes:

  • safe – nunca auto-migra las bases de datos. Es como decir: Voy a hacerlo yo mismo (a mano).
  • alter – auto-migra, pero tratando de mantener los datos existentes (experimental).
  • drop – limpia todos los datos y reconstruye los modelos cada vez que se corre sails lift.

Generadores

Sails viene con varios generadores para ayudar a realizar los andamios de nuevas aplicaciones. También es permite que cualquiera pueda crear sus propios generadores para manejar tareas frecuentes, o ampliar la funcionalidad (por ejemplo, mediante la creación de un generador que da salida a archivos de vista de su lenguaje de plantillas favorito).

Por favor consulte: Generate

Configurar config/connections.js

Los adaptadores:

  • Son el intermediario entre nuestra aplicación Sails y algún tipo de almacenamiento (generalmente una base de datos).
  • Se configuran en el archivo config/connections.js de la aplicación. En este archivo se pueden crear diferentes “ajustes guardados” globales que se pueden mezclar y combinar desde los modelos.
  • Existen adaptadores en Sails para una variedad de bases de datos populares, tales como MySQL, Postgres y Mongo.

Por favor consulte: Blueprint API

Crear

curl -is -X POST -d "username=josoroma&email=josoroma@example.com" http://localhost:1337/user

curl -is -X POST -d "username=celine&email=celine@example.com" http://localhost:1337/user
HTTP/1.1 200 OK

{
  "username": "josoroma",
  "email": "josoroma@example.com",
  "createdAt": "2014-11-23T18:11:44.350Z",
  "updatedAt": "2014-11-23T18:11:44.350Z",
  "id": 1
}
{
  "username": "celine",
  "email": "celine@example.com",
  "createdAt": "2014-11-23T18:11:45.337Z",
  "updatedAt": "2014-11-23T18:11:45.337Z",
  "id": 2
}
curl -is -X POST -d "username=uifi&email=uifi@example.com" http://localhost:1337/user/create

curl -is -X POST -d "username=coco&email=coco@example.com" http://localhost:1337/user/create
 HTTP/1.1 200 OK

{
  "username": "uifi",
  "email": "uifi@example.com",
  "createdAt": "2014-11-23T18:12:14.281Z",
  "updatedAt": "2014-11-23T18:12:14.281Z",
  "id": 3
}
{
  "username": "coco",
  "email": "coco@example.com",
  "createdAt": "2014-11-23T18:12:15.118Z",
  "updatedAt": "2014-11-23T18:12:15.118Z",
  "id": 4
}

Listar

curl -is http://localhost:1337/user

curl -is http://localhost:1337/user/find

HTTP/1.1 200 OK

[
  {
    "username": "josoroma",
    "email": "josoroma@example.com",
    "createdAt": "2014-11-23T18:11:44.350Z",
    "updatedAt": "2014-11-23T18:11:44.350Z",
    "id": 1
  },
  {
    "username": "celine",
    "email": "celine@example.com",
    "createdAt": "2014-11-23T18:11:45.337Z",
    "updatedAt": "2014-11-23T18:11:45.337Z",
    "id": 2
  },
  {
    "username": "uifi",
    "email": "uifi@example.com",
    "createdAt": "2014-11-23T18:12:14.281Z",
    "updatedAt": "2014-11-23T18:12:14.281Z",
    "id": 3
  },
  {
    "username": "coco",
    "email": "coco@example.com",
    "createdAt": "2014-11-23T18:12:15.118Z",
    "updatedAt": "2014-11-23T18:12:15.118Z",
    "id": 4
  }
]

Un Registro

curl -is http://localhost:1337/user/find/1

curl -is -d "id=1" http://localhost:1337/user/find

curl -is -d "username=josoroma" http://localhost:1337/user/find

HTTP/1.1 200 OK

{
  "username": "josoroma",
  "email": "josoroma@example.com",
  "createdAt": "2014-11-23T18:11:44.350Z",
  "updatedAt": "2014-11-23T18:11:44.350Z",
  "id": 1
}

Actualizar

curl -is -X PATCH -d "username=josepablo"  http://localhost:1337/user/update/1

HTTP/1.1 200 OK

{
  "username": "josepablo",
  "email": "josoroma@example.com",
  "createdAt": "2014-11-23T18:11:44.350Z",
  "updatedAt": "2014-11-23T18:17:07.673Z",
  "id": 1
}
curl -is -X PUT -d "username=josoroma&email=example@josoroma.com"  http://localhost:1337/user/update/1

HTTP/1.1 200 OK

{
  "username": "josoroma",
  "email": "example@josoroma.com",
  "createdAt": "2014-11-23T18:11:44.350Z",
  "updatedAt": "2014-11-23T19:14:20.633Z",
  "id": 1
}

Borrar

curl -is -X DELETE http://localhost:1337/user/destroy/1

HTTP/1.1 200 OK

{
  "username": "josoroma",
  "email": "josoroma@example.com",
  "createdAt": "2014-11-23T18:11:44.350Z",
  "updatedAt": "2014-11-23T19:14:20.633Z",
  "id": 1
}
curl -is -X DELETE http://localhost:1337/user/destroy/1

HTTP/1.1 404 Not Found

No record found with the specified `id`.

Comprobar

curl -s http://localhost:1337/user

curl -is http://localhost:1337/user/find

HTTP/1.1 200 OK

[
  {
    "username": "celine",
    "email": "celine@example.com",
    "createdAt": "2014-11-23T18:11:45.337Z",
    "updatedAt": "2014-11-23T18:11:45.337Z",
    "id": 2
  },
  {
    "username": "uifi",
    "email": "uifi@example.com",
    "createdAt": "2014-11-23T18:12:14.281Z",
    "updatedAt": "2014-11-23T18:12:14.281Z",
    "id": 3
  },
  {
    "username": "coco",
    "email": "coco@example.com",
    "createdAt": "2014-11-23T18:12:15.118Z",
    "updatedAt": "2014-11-23T18:12:15.118Z",
    "id": 4
  }
]

Interacción agil con REST APIs

Postman

En Chrome es la herramienta más eficiente para probar, desarrollar y documentar una API. Agil para crear solicitudes complejas, volver atrás en el tiempo y ver los resultados de una manera amigable.

HTTPie

HTTPie es un cliente HTTP que se puede usar desde la línea de comandos, parece más fácil de usar que Curl.

curl -I http://reqr.es

HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Sun, 23 Nov 2014 04:44:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 10944
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *
ETag: W/"CenpWUsIvfcCYkB+PleqTA=="

Imprimir la respuesta en formato JSON amigable

curl -s http://reqr.es/api/users | xargs -0 node -e 
"console.log(JSON.stringify(JSON.parse(process.argv[1]), null, 2))"

npm install -g json

curl -s http://reqr.es/api/users | json
{
  "page": 1,
  "per_page": 3,
  "total": 12,
  "total_pages": 4,
  "data": [
    {
      "id": 1,
      "first_name": "george",
      "last_name": "bluth",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"
    },
    {
      "id": 2,
      "first_name": "lucille",
      "last_name": "bluth",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
    },
    {
      "id": 3,
      "first_name": "oscar",
      "last_name": "bluth",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"
    }
  ]
}

Estilo YAML con color

npm install -g prettyjson
curl -s http://reqr.es/api/users | prettyjson

Mi favorito es underscore-cli

npm install -g underscore-cli
curl -s http://reqr.es/api/users | underscore print --color

GET

curl -is http://reqr.es/api/users
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Sun, 23 Nov 2014 05:10:18 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 446
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *
ETag: W/"1be-539742e1"

{"page":1,"per_page":3,"total":12,"total_pages":4,"data":[{"id":1,"first_name":"george","last_name":"bluth","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"},{"id":2,"first_name":"lucille","last_name":"bluth","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"},{"id":3,"first_name":"oscar","last_name":"bluth","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"}]}

POST

curl -is -X POST -d "name=Josoroma&job=Ninja" http://reqr.es/api/users
HTTP/1.1 201 Created
Server: nginx/1.6.2
Date: Sun, 23 Nov 2014 05:13:16 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 82
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *

{"name":"Josoroma","ob":"Ninja","id":"993","createdAt":"2014-11-23T05:13:16.017Z"}

PUT

curl -is -X PUT -d "name=Josoroma&job=Monk" http://reqr.es/api/users/2
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Sun, 23 Nov 2014 05:14:31 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 71
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *

{"name":"Josoroma","job":"Monk","updatedAt":"2014-11-23T05:14:31.618Z"}

DELETE

curl -is -X DELETE -d "name=Josoroma" http://reqr.es/api/users/2
HTTP/1.1 204 No Content
Server: nginx/1.6.2
Date: Sun, 23 Nov 2014 05:19:28 GMT
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *

Listar

curl -is http://jsonplaceholder.typicode.com/posts/1

Crear

curl -is -X POST -d "title=Heading&body=Content&userId=1" http://jsonplaceholder.typicode.com/posts

Actualizar

curl -is -X PUT -d "title=New Updated Heading&body=New Updated Content&userId=1" http://jsonplaceholder.typicode.com/posts/1
curl -is -X PATCH -d "title=New Patched Heading" http://jsonplaceholder.typicode.com/posts/1

Borrar

curl -is -X DELETE http://jsonplaceholder.typicode.com/posts/1

Filtrar

curl -s http://jsonplaceholder.typicode.com/posts?userId=1

Listar Recursos Anidados

curl -s http://jsonplaceholder.typicode.com/posts/1/comments

SailsJS Baby Steps

¿Qué es Sails?

Sails permite que sea fácil construir aplicaciones Node.js empresariales (estables y fiables) a la medida. Está diseñado para emular el patrón MVC de “frameworks” bien conocidos como Ruby on Rails, CakePHP y Django, pero soportando los requisitos de aplicaciones modernas: APIs basados en datos con una arquitectura orientada en servicios escalables. Especialmente efectivo para la construcción de chats y tableros de control en tiempo real, también es ideal para la construcción de juegos multi-jugador; pero se puede utilizar para cualquier proyecto o aplicación Web.

Introducción a Sails

Estructura MVC

  • Facilita modelos agnósticos de almacenamiento.
  • Controladores basados en un “blueprint”.
    Los controladores son pegados (“middleware”) con Express (para gestionar y hablar HTTP).
    Por ejemplo, una petición HTTP entra al servidor Web y Express provee toda la funcionalidad para responder un adecuada respuesta HTTP.
  • Las vistas del lado del servidor se presentan o dibujan basadas en el controlador. Se enfatizan en entregar un API, generalmente en formato JSON (entrega contra un URL), pero también soporta la generación de otros tipos de vistas basadas en controladores.

Nota: En la industria de la computación, el “middleware” es un término general para cualquier programación que sirve para “pegar entre sí” o mediar entre dos programas separados y, a menudo ya existentes.

Plantillas del lado del servidor

EJS limpia el HTML producido por JavaScript con el uso de plantillas del lado del cliente. Después de que EJS pone sus guantes en el código sucio, te vas a sentir más organizado y ordenado.

Pero también se puede extender a usar Handlebars o Jade.

Object-relational mapping (ORM Layer)

Waterline es un nuevo tipo de motor de almacenamiento y recuperación.

Adaptadores Agnósticos

Proporciona un API uniforme para acceder a cosas de diferentes tipos de bases de datos, protocolos y APIs de terceros. Esto significa que usted escribe el mismo código para obtener y almacenar cosas como datos de los usuarios, ya sea que vivan en Redis, MySQL, LDAP, MongoDB o Postgres. También se “pega” bien con APIs remotos como Twitter. Esto que permite que cualquier módulo en nuestra aplicación puede soportar diferentes adaptadores adicionales.

Modularidad

Waterline se esfuerza en heredar las mejores partes de ORMs conocidos como ActiveRecord, Hibernate, y Mongoose (“Object Modeling for Node.js”), pero con una nueva perspectiva y énfasis en la modularidad, capacidad de prueba, y la coherencia entre los adaptadores.

Nota: El mapeo objeto-relacional (ORM, O/RM, y O/R mapeo) en ciencias de la computación es una técnica de programación para la conversión de datos entre sistemas de tipos incompatibles en los lenguajes de programación orientados a objetos. Esto crea, en efecto, una “base de datos de objeto virtual” que se puede utilizar desde dentro del lenguaje de programación.

Policies

Siguen una estructura muy simple, son un “Express Middleware Callback”. Por convención corren antes de llegar a cualquier acción del controlador o a alguna acción específica del controlador.

Algunos de sus usos permiten:

  • Decorar datos de sesión.
  • Autenticación.

Para más información:

Soporte en tiempo real con Socket.io (req, res y next)

Socket.IO permite una comunicación en tiempo real y bidireccional basada en eventos. Funciona en todas las plataformas, navegadores Web o dispositivos, centrándose también en la fiabilidad y la velocidad.

  • Magia interna (traducción de rutas) todos responden a través de “sockets” o “http”.
  • Unifica la lógica del negocio.
  • Se extiende para agregar (broadcast events and join channels) res.broadcast() y req.join() para soportar un pubsub básico.

API Blueprints

Una vez que se crea un modelo con Sails, este provee de manera automática todos los “CRUD Blueprints” básicos, incluyendo búsqueda, ordenamiento y paginación. Son como “rutas mágicas” disponibles que no necesitan ser definidas.

Grunt-based Asset Pipeline

Sails usa Grunt para el manejo de tareas.

  • Auto-compila CSS Processors (LESS y Sass), CoffeScipt, etc.
  • Los assets son automáticamente combinados e inyectados en el DOM.
  • Soporta los modos de Desarrollo y Producción.

Sails es fácil de extender

Adaptadores

Los adaptadores Waterline soportan fuentes SQL, NoSQL y WebServices.

Generadores

Se pueden producir generadores a la medida para hacer scaffold en nuestra aplicación (CLI).

Hooks (todo es un hook)

El core de Sails es muy flexible y se puede extender de manera fácil mediante hooks.

Creating a Web App from scratch

Cosas que necesito tatuarme sobre PHP y OOP

¿Cuándo debo usar require o include?

La función require() es idéntica a include(), excepto que controla los errores de manera diferente. Si se produce un error, la función include() genera una advertencia, pero el script seguirá con su ejecución. Por otro lado, El require() genera un error fatal, por lo que el script se detendrá.

¿Cuándo debo usar require_once o require?

La declaración require_once () es idéntica a require(), pero PHP comprobará si el archivo ya se ha incluido, y si es así, no lo incluye otra vez.

Interfaces

Las clases abstractas son una característica mal entendida de la programación en PHP orientada a objetos (OOP) y la fuente de confusión surge cuando se considera frente a una interfaz.

¿Cuándo debo usar interfaces?

La razón obvia para usar una interfaz es que una clase hija puede implementar varias interfaces, pero sólo puede extender una única clase abstracta.

¿Cuándo debo usar clases abstractas?

Cuando no se requiere hacer uso de herencia múltiple se recomienda usar clases abstractas, simplemente porque permiten más tarde añadir funcionalidad básica dentro de la clase abstracta. Sin embargo las razones de la creación de clases abstractas debe ser más que eso.

“Abstract” sólo indica que algo fue declarado pero no definido, por lo que antes de usarlo, es necesario definirlo.

¿Por qué debo utilizar clases abstractas?

Una clase abstracta proporciona funciones base concretas, así como funciones abstractas que deben ser implementadas por clases concretas hijas que se vinculan por algo que llamaremos: un contrato.

El brillo sutil de las clases abstractas

Pueden llamar a funciones abstractas dentro de las funciones de la base concreta. Por ejemplo:

abstract class Vehicle { 
  function start() { 
    $ready = $this->drive();      // Existe en la clase hija por contrato.
    return strtoupper($ready); 
  } 
  abstract function drive();      // Este es el contrato.
} 
 
class Car extends Vehicle { 
  function drive() {              // Esta implementación concreta es obligatoria.
    return "Please accelarate your car."; 
  } 
} 

class Motorcycle extends Vehicle {
  // Actually you ride a motorcycle.
  function drive() {              // Esta implementación concreta es obligatoria.
    return "Please accelarate your motorcycle."; 
  } 
} 
 
$car = new Car(); 
echo $car->start();

$motorcycle = new Motorcycle(); 
echo $motorcycle->start();

Para comprender mejor las clases abstractas:

  • Herencia simple. Las clases hijas sólo pueden extender sólo una clase a la vez.
  • Las clases abstractas no pueden ser instanciadas – no se usa new Vehicle();
  • Las clases abstractas sólo pueden definir variables de clase del tipo const.
  • La clase abstracta A puede ser extendida por otra clase abstracta B. La clase B puede implementar alguna o ninguna de las funciones abstractas en A.
  • En el caso anterior, una clase hija C que extiende a la clase abstracta B debe implementar todas las funciones abstractas de B, así como las funciones abstractas en A que no se hayan implementado en la clase abstracta B.
  • Los parámetros de las funciones concretas y las funciones abstractas deben coincidir. Sin embargo, si una función abstracta se define como función abstracta turnOff($message); entonces está bien implementarla como turnOff($message, $lock = TRUE), pero no como turnOff($message, $lock).
  • La visibilidad de las funciones en las clases hijas debe ser la mismo o menos restrictiva que las de la clase madre. Por lo tanto protected abstract function puede ser implementada como protected o public pero no como private.
  • Arriba de PHP 5.3 si es permitido declarar funciones como static abstract.

A diferencia de las interfaces, las clases abstractas si son clases. Estas son otras características:

  • Las clases abstractas pueden tener “consts”, “members”, “method stubs” y “defined methods”, mientras que las interfaces sólo pueden tener “consts” y  “method stubs“.
  • Los métodos y los miembros de una clase abstracta se pueden definir con cualquier visibilidad, mientras que todos los métodos de una interfaz se deben definir como públicos.
  • Al heredar una clase abstracta, la clase hija debe definir los métodos abstractos, mientras que una interfaz puede extender otra interfaz y no es necesario que los métodos deban ser definidos.
  • Una clase hija sólo puede extender una sola clase abstracta (o cualquier otra), mientras que una interfaz se puede extender, también una clase puede implementar otras múltiples interfaces.
  • Una clase hija puede definir métodos abstractos con la misma o visibilidad menor restrictiva, mientras que una clase que implementa una interfaz debe definir los métodos con la misma visibilidad exacta.

Abstract Class vs Final Class/”Class Constant”

  • Una clase abstracta no puede ser instanciada. En otras palabras, no podemos crear directamente el objeto de la clase abstracta. Pero con las clases final sí podemos crear una instancia.
  • Una clase abstracta debe ser extendida mientras una clase final no lo puede ser.
  • Una clase final no puede contener métodos abstractos, pero una clase abstracta sí puede contener métodos final.

Traits

Arriba de PHP 5.4, las clases abstractas son antigüedades y no deben utilizarse. La clara separación de las interfaces y los traits proporciona los mismos beneficios DRY y son menos restrictivos para el desarrollador.

Los traits no implican una relación. Son puramente reutilización de código. En tiempo de ejecución, los traits no existen. No dicen nada acerca de un objeto que los utiliza, cómo se comportan, lo que puede hacer con ellos, o cualquier otra cosa. Los traits son puramente reutilización de código. En ese sentido, son completamente ortogonales a las interfaces; mientras que una interfaz es la reutilización puramente de la interfaz, un trait es puramente reutilización de código.

Las clases abstractas existen para apoyar a los desarrolladores de PHP 5.3, que aún no tienen acceso a los traits.