Es un estilo de arquitectura, no es una especificación ni un estándar. Aunque REST no es un estándar, está basado en estándares:
- HTTP
- URL
- Representación de los recursos: XML/HTML/GIF/JPEG/...
- Tipos MIME: text/xml, text/html, ...
Principios o Restricciones:
- Recursos deben ser uniformemente accesibles (URI única).
- Recursos son accedidos y actualizados por mediante operaciones GET, POST, PUT, DELETE
- Metadatos para describir recursos
- Comunicación entre cliente y servidor debe ser Stateless.
- La descripción de un servicio debe ser hecha en WSDL.
- Stateless (Sin estado): Cada petición de un cliente debe contener toda la información necesaria. No puede beneficiarse de contexto almacenado en servidor.
Web Services con REST y WCF
Primero, en la base de datos agregaremos la tabla “tb_empleado”, con la siguiente estructura:
Segundo, crearemos un nuevo Proyecto en Visual Studio 2010 de tipo WCF de nombre RESTServices.
Crearemos una carpeta "Dominio" y agregaremos la clase "Empleado.cs" con el siguiente código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
namespace RESTServices.Dominio
{
[DataContract]
public class Empleado
{
[DataMember]
public int Codigo { get; set; }
[DataMember]
public int DNI { get; set; }
[DataMember]
public string Nombre { get; set; }
[DataMember]
public string Apellido { get; set; }
[DataMember]
public string FechaNacimiento { get; set; }
[DataMember]
public string Telefono { get; set; }
[DataMember]
public int Estado { get; set; }
[DataMember]
public string Usuario { get; set; }
[DataMember]
public string Clave { get; set; }
}
}
Crearemos otra carpeta "Persistencia" y agregaremos las clases "Conexion.cs", "EmpleadoDAO" con los siguientes códigos respectivamente:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace RESTServices.Persistencia
{
public class ConexionUtil
{
public static string Cadena
{
get
{
return "Data Source=(local);Initial Catalog=bd_peaje;Integrated Security=SSPI;";
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using RESTServices.Dominio;
using System.Data.SqlClient;
using System.ServiceModel.Web;
using System.Net;
namespace RESTServices.Persistencia
{
public class EmpleadoDAO
{
public Empleado Crear(Empleado empleadoACrear)
{
Empleado empleadoNuevo = null;
empleadoACrear.Codigo = ObtenerIdCorrelativo();
string sql = "INSERT INTO tb_empleado VALUES (@cod,@dni, @nom,@ape, @fecnac, @fono,@estado,@usu,@clave)";
using (SqlConnection con = new SqlConnection(ConexionUtil.Cadena))
{
con.Open();
using (SqlCommand com = new SqlCommand(sql, con))
{
com.Parameters.Add(new SqlParameter("@cod", empleadoACrear.Codigo));
com.Parameters.Add(new SqlParameter("@dni", empleadoACrear.DNI));
com.Parameters.Add(new SqlParameter("@nom", empleadoACrear.Nombre));
com.Parameters.Add(new SqlParameter("@ape", empleadoACrear.Apellido));
com.Parameters.Add(new SqlParameter("@fecnac", empleadoACrear.FechaNacimiento));
com.Parameters.Add(new SqlParameter("@fono", empleadoACrear.Telefono));
com.Parameters.Add(new SqlParameter("@estado", empleadoACrear.Estado));
com.Parameters.Add(new SqlParameter("@usu", empleadoACrear.Usuario));
com.Parameters.Add(new SqlParameter("@clave", empleadoACrear.Clave));
com.ExecuteNonQuery();
}
}
empleadoNuevo = Obtener(empleadoACrear.Codigo);
return empleadoNuevo;
}
public Empleado Obtener(int codigo)
{
Empleado empleadoExistente = null;
string sql = "SELECT * FROM tb_empleado WHERE codEmpleado=@cod";
using (SqlConnection con = new SqlConnection(ConexionUtil.Cadena))
{
con.Open();
using (SqlCommand com = new SqlCommand(sql, con))
{
com.Parameters.Add(new SqlParameter("@cod", codigo));
using (SqlDataReader resultado = com.ExecuteReader())
{
if (resultado.Read())
{
empleadoExistente = new Empleado()
{
Codigo = (int)resultado["codEmpleado"],
DNI=(int)resultado["dni"],
Nombre = (string)resultado["nombres"],
Apellido = (string)resultado["apellidos"],
FechaNacimiento = (string)resultado["fechaNacimiento"],
Telefono = (string)resultado["telefono"],
Estado=(int)resultado["estado"],
Usuario = (string)resultado["usuario"],
Clave = (string)resultado["clave"]
};
}
}
}
}
return empleadoExistente;
}
public Empleado ObtenerDNI(int dni)
{
Empleado empleadoExistente = null;
string sql = "SELECT dni FROM tb_empleado WHERE dni=@dni";
using (SqlConnection con = new SqlConnection(ConexionUtil.Cadena))
{
con.Open();
using (SqlCommand com = new SqlCommand(sql, con))
{
com.Parameters.Add(new SqlParameter("@dni", dni));
using (SqlDataReader resultado = com.ExecuteReader())
{
if (resultado.Read())
{
empleadoExistente = new Empleado()
{
DNI = (int)resultado["dni"],
};
}
}
}
}
return empleadoExistente;
}
public Empleado ObtenerUsuario(string usuario)
{
Empleado empleadoExistente = null;
string sql = "SELECT codEmpleado,usuario FROM tb_empleado WHERE usuario=@usuario";
using (SqlConnection con = new SqlConnection(ConexionUtil.Cadena))
{
con.Open();
using (SqlCommand com = new SqlCommand(sql, con))
{
com.Parameters.Add(new SqlParameter("@usuario", usuario));
using (SqlDataReader resultado = com.ExecuteReader())
{
if (resultado.Read())
{
empleadoExistente = new Empleado()
{
Codigo = (int)resultado["codEmpleado"],
Usuario = (string)resultado["usuario"]
};
}
}
}
}
return empleadoExistente;
}
public Empleado Modificar(Empleado empleadoAModificar)
{
Empleado empleadoModificado = null;
string sql = "UPDATE tb_empleado SET dni=@dni,nombres=@nom,apellidos=@ape,fechaNacimiento=@fecnac,telefono=@tel,estado=@est,usuario=@usu,clave@cla WHERE codEmpleado=@cod";
using (SqlConnection con = new SqlConnection(ConexionUtil.Cadena))
{
con.Open();
using (SqlCommand com = new SqlCommand(sql, con))
{
com.Parameters.Add(new SqlParameter("@cod", empleadoAModificar.Codigo));
com.Parameters.Add(new SqlParameter("@dni", empleadoAModificar.DNI));
com.Parameters.Add(new SqlParameter("@nom", empleadoAModificar.Nombre));
com.Parameters.Add(new SqlParameter("@ape", empleadoAModificar.Apellido));
com.Parameters.Add(new SqlParameter("@fecnac", empleadoAModificar.FechaNacimiento));
com.Parameters.Add(new SqlParameter("@tel", empleadoAModificar.Telefono));
com.Parameters.Add(new SqlParameter("@est", empleadoAModificar.Estado));
com.Parameters.Add(new SqlParameter("@usu", empleadoAModificar.Usuario));
com.Parameters.Add(new SqlParameter("@clave", empleadoAModificar.Clave));
com.ExecuteNonQuery();
}
}
empleadoModificado = Obtener(empleadoAModificar.Codigo);
return empleadoModificado;
}
public void Eliminar(Empleado empleadoAEliminar)
{
string sql = "DELETE FROM tb_empleado WHERE codEmpleado=@cod";
using (SqlConnection con = new SqlConnection(ConexionUtil.Cadena))
{
con.Open();
using (SqlCommand com = new SqlCommand(sql, con))
{
com.Parameters.Add(new SqlParameter("@cod", empleadoAEliminar.Codigo));
com.ExecuteNonQuery();
}
}
}
public List ListarTodos()
{
List empleadoExistentes = new List();
Empleado empleadoExiste = null;
string sql = "SELECT * FROM tb_empleado";
using (SqlConnection con = new SqlConnection(ConexionUtil.Cadena))
{
con.Open();
using (SqlCommand com = new SqlCommand(sql, con))
{
using (SqlDataReader resultado = com.ExecuteReader())
{
while (resultado.Read())
{
empleadoExiste = new Empleado()
{
Codigo = (int)resultado["codEmpleado"],
DNI = (int)resultado["dni"],
Nombre = (string)resultado["nombres"],
Apellido = (string)resultado["apellidos"],
FechaNacimiento = (string)resultado["fechaNacimiento"],
Telefono = (string)resultado["telefono"],
Estado = (int)resultado["estado"],
Usuario = (string)resultado["usuario"],
Clave = (string)resultado["clave"]
};
empleadoExistentes.Add(empleadoExiste);
}
}
}
}
return empleadoExistentes;
}
public int ObtenerIdCorrelativo()
{
int idMax = 0;
string sql = "SELECT isNull(max(codEmpleado),0)+1 as Id FROM tb_empleado ";
using (SqlConnection con = new SqlConnection(ConexionUtil.Cadena))
{
con.Open();
using (SqlCommand com = new SqlCommand(sql, con))
{
using (SqlDataReader resultado = com.ExecuteReader())
{
if (resultado.Read())
{
idMax = (int)resultado["Id"];
}
}
}
}
return (idMax);
}
}
}
Crearemos un servicio web "Empleados.svc"
Editaremos el archivo "IEmpleados.cs" y agregamos los siguientes métodos:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
using RESTServices.Dominio;
namespace RESTServices
{
[ServiceContract]
public interface IEmpleados
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "Empleados", ResponseFormat = WebMessageFormat.Json)]
Empleado CrearEmpleado(Empleado empleadoACrear);
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "Empleados/{codigo}", ResponseFormat = WebMessageFormat.Json)]
Empleado ObtenerEmpleado(string codigo);
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "Empleados?dni={dni}", ResponseFormat = WebMessageFormat.Json)]
Empleado ObtenerEmpleadoDNI(string dni);
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "Usuarios?usuario={usuario}", ResponseFormat = WebMessageFormat.Json)]
Empleado ObtenerEmpleadoUsuario(string usuario);
[OperationContract]
[WebInvoke(Method = "PUT", UriTemplate = "Empleados", ResponseFormat = WebMessageFormat.Json)]
Empleado ModificarEmpleado(Empleado empleadoAModificar);
[OperationContract]
[WebInvoke(Method = "DELETE", UriTemplate = "Empleados", ResponseFormat = WebMessageFormat.Json)]
void EliminarEmpleado(string codigo);
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "Empleados", ResponseFormat = WebMessageFormat.Json)]
List ListarEmpleados();
}
}
Editaremos el archivo "IEmpleados.svc.cs" e implementaremos los métodos creados:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using RESTServices.Persistencia;
using System.Data.SqlClient;
using RESTServices.Dominio;
using System.ServiceModel.Web;
using System.Net;
namespace RESTServices
{
public class Empleados : IEmpleados
{
EmpleadoDAO dao = new EmpleadoDAO();
public Dominio.Empleado CrearEmpleado(Dominio.Empleado empleadoACrear)
{
string dni =Convert.ToString(empleadoACrear.DNI);
Empleado existe =ObtenerEmpleadoDNI(dni);
if (existe != null)
throw new WebFaultException(
new MensajeError()
{
Codigo = "E01",
Mensaje = "El empleado ya se encuentra registrado"
},
HttpStatusCode.InternalServerError);
return dao.Crear(empleadoACrear);
}
public Dominio.Empleado ObtenerEmpleado(string codigo)
{
int x = int.Parse(codigo);
return dao.Obtener(x);
}
public Dominio.Empleado ObtenerEmpleadoDNI(string dni)
{
int x = int.Parse(dni);
return dao.ObtenerDNI(x);
}
public Empleado ObtenerEmpleadoUsuario(string usuario)
{
return dao.ObtenerUsuario(usuario);
}
public Dominio.Empleado ModificarEmpleado(Empleado empleadoAModificar)
{
return dao.Modificar(empleadoAModificar);
}
public void EliminarEmpleado(string codigo)
{
int x = int.Parse(codigo);
dao.Eliminar(dao.Obtener(x));
}
public List ListarEmpleados()
{
return dao.ListarTodos().ToList();
}
}
}
Añadimos WebServiceHostFactory que es una clase introducida en WCF para hacer servicios WCF Restful.
Para testear instalamos un complemento del Firefox "REST Client"
Por último, probamos nuestros servicios REST.