Serverless architecture: Amazon vs Azure


I’ve been reading about serverless architecture, starting in this article http://martinfowler.com/articles/serverless.html, written by Martin Fowler.

Yes, sure, and now you are going to summarize the article.

Not at all, italic voice, I am trying to add more value to that article and, at the same time, take some notes I can review in the future.

As Martin Fowler was talking a lot about AWS Lambda, I was trying to see if there is something similar in Azure because, as Amazon says, Lambda functions are to be written in Java, Node.js or Python and neither of those is my main backend language. I have nothing against none of those languages or against Amazon, but, if I can choose, I prefer to write code in C# and deploy it to Azure (and I believe I am not the only case), just because of my knowledge and experience. I’ve been reading from lots of different websites and I have written this article not with my own experience, but with my compendium of information obtained.

So, let me understand, all this article is because you don’t know how to write code in Python?

No, italic voice, I don’t mind learning new languages, I think it is a good thing, the point here is, there are more actors in the market and, as a TA, I need to know the most relevant to offer alternatives to my clients.

I assume that not many companies are ready for such a huge change of philosophy and, more than the companies, the IT teams behind them. If exposing data from their well protected backend to the outside, even throughout very well secured API Gateways is seen like a weakness in some IT departments, if we remove the backend server from the equation, the heat is starting to hit the room. The idea of losing control of their servers would drive crazy more than one security engineer. The idea of the neediness of their services to configure scalable virtual machines, would make more than one job obsolete. It is our responsibility to give good and enough information to our clients when we propose a solution for a problem, and provide good reasons for the change and, in order to do that, research is our allied, with research we can answer the why’s and the how’s. I tried to do that in this article, at least, for me as a notebook.

Uh huh! Gotcha! What you want is a justification to remove people from projects!

Not at all, italic voice, what I need to understand, is the differences between platforms, because perhaps in the near future I will need to advice some client with them.

Let’s be clear, serverless does not mean no server is used, it means, according to ThoughtWorks: “Serverless architecture replaces long-running virtual machines with ephemeral compute power that comes into existence on request and disappears immediately after use.” So, yes, there is a server. The main difference is you don’t have to care about scale, provision or operation.

Such an architecture is really efficient in terms of compute power, but, on the other hand, makes harder to deploy, manage and share code amongst services.

So, lately I read a lot about AWS Lambda but, surprisingly, I haven’t found too much information regarding the equivalent in Microsoft Azure. There is an equivalent and, as there is, it is needed to be compared before to advise any client willing to start thinking on this cutting edge architecture.

More info in AWS Lambda here: https://aws.amazon.com/lambda/

More info in Azure Functions here: https://azure.microsoft.com/en-us/documentation/articles/functions-overview/

So, which one is better? As usually, it depends. Do you need to write the code in C#? You can’t use Lambda. Do you need to deploy your serverless architecture on premises? You can’t use Lambda. I’ve read somewhere (I don’t really know where at the moment of writing this) that Lambda supports up to 100 concurrent executions and Functions only 10. In that case, Lambda is the winner. Let’s get into some details and differences between them:

Languages:

Lambda supports Java, Node.js and Python… for now.

Functions supports C#, F#, Node.js and PHP. They also claim for Java, bash and batch files, but I believe those are still in beta.

Organization:

Functions are organized in something called App Service which is a group of functions that share memory. This is radically different in Lambda, where you allocate memory per function. This concept is important, because in Azure, you pay per time and memory used.

Deployment:

Functions can be deployed using just an FTP client, but, also, you can link your CI environment to the deployment folder easily, including TFS, Git and even OneDrive and others.

One important thing in the CI aspect is the versioning. Functions does not support versioning while Lambda does.

I am no expert in Lambda, but I’ve read about some third party tools to deploy the functions, for instance, here you have something to test and deploy (Node.js) (https://www.npmjs.com/package/aws-lambda-toolkit).

Execution:

Microsoft Azure Functions are open source. Yes, you’ve read right. They are open source, like almost everything new Microsoft is doing, so, yes, you can run it locally. On the other hand, Lambda is not, but I’ve read about some custom tools created to run the functions locally before to deploy.

Wait, no way, Microsoft open source, since when?

Yes, italic voice, since the new CEO took control of Microsoft, a lot of things have changed, like that, for instance, if you search for Microsoft Open Source code in GitHub, you will be amazed…

Functions does not have an execution limit, but Lambda does. Why is this important? Because of billing. With Lambda you can be sure that even though you have a sleepy process that is taking forever to execute (not a normal behavior), that process will be killed in 5 minutes. In Azure, you can be sure your bill will be huge if you are not monitoring the functions closely.

Ok, so after all that literature in favour of Microsoft, you are saying that Lambda is better?

No, italic voice, I am not saying that, in fact, I am not in favour of Microsoft nor Amazon what I say is that, after some research, it seems to me that AWS Lambda is being adopted prior to Functions because:

  • They are Amazon
  • They were there first
  • They are not Microsoft
  • And yes, they are Amazon

And many people are not considering Microsoft seriously and they should. But, that said, that is my opinion and I hope this article can be as a starting poing of a discussion that help me and others to understand better Serverless Architecture, what vendor advice to clients and why.

 

I hope you enjoyed the reading.

 

Victor

Thanks to www.cienciadesofa.com for the italic voice idea.

[NameAttribute] Workaround in WebApi HelpPage


[NameAttribute] Workaround in Microsoft.AspNet.WebApi.HelpPage

The Nuget package Microsoft.AspNet.WebApi.HelpPage is really helpful to automatically create the needed help for your web api. But, sometimes, depending on your solution structure, can be difficult to use it.

The package works really fine, smooth and unassisted when you have the standard MVC template in your web api project, but, what happen if we complicate it a bit? For instance, in a bigger solution, we might want to split the models in an independent project and, besides, we have the same name of a class but in a different namespace. Personally I prefer to have different name of classes for different purposes, even if they are in different namespaces, but, sometimes, you have to choose between adding prefixes of suffixes to the classes names, or having the same name.

Let’s do a small test. First of all, we create an MVC application with a WebAPI (or simply a Web API application, it does not matter for this article but I decided to start with this template to show how to add a Help Page from the scratch):

CreateProject

 

 

 

selectTemplates

 

 

 

 

 

 

 

 

If we run the application we can see the standard base application executing. Let’s add, to that application, a new ApiController with a model:

selectTemplates

 

 

 

 

 

 

 

 

And let’s name this controller “MoneyBanksController”. The template that will be created will be similar to this one:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace HelpPageErrorSimulator.Controllers
{
public class MoneyBanksController : ApiController
{

// GET: api/MoneyBanks
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}

// GET: api/MoneyBanks/5
public string Get(int id)
{
return "value";
}

// POST: api/MoneyBanks
public void Post([FromBody]string value)
{

}

// PUT: api/MoneyBanks/5
public void Put(int id, [FromBody]string value)
{

}

// DELETE: api/MoneyBanks/5
public void Delete(int id)
{

}

}

}

Now, let’s change the template “string” type by a new class named “Bank”. The result will be something like this:

{

// GET: api/MoneyBanks
public IEnumerable<Bank> Get()
{
return new Bank[] { new Bank(), new Bank() };
}

// GET: api/MoneyBanks/5
public string Get(int id)
{
return "value";
}

// POST: api/MoneyBanks
public void Post([FromBody]Bank value)
{

}

// PUT: api/MoneyBanks/5
public void Put(int id, [FromBody]Bank value)
{

}

// DELETE: api/MoneyBanks/5
public void Delete(int id)
{

}

}

Of course, as we didn’t write the Bank class yet, it appears in red. Let’s create the class inside the Models folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace HelpPageErrorSimulator.Models
{

public class Bank
{

public string Name { get; set; }

public string Special1 { get; set; }

public string Special2 { get; set; }

}

}

Now we can go back to the MoneyBanks controller and add a reference to the namespace containing the Bank class:

using HelpPageErrorSimulator.Models;

Now we can add the HelpPages nuget package. To do that, open the Package Manager Console and write this command:

PM> install-package Microsoft.AspNet.WebApi.HelpPage

If we run the application now, we are able to navigate to the url “/help” and we will see the help page for the controller we wrote. Pretty simple, huh?

Browser con API

 

 

 

 

 

 

Let’s complicate the system a bit. In a big application, you should have your models in an external project, that way, if you have a N-layer architecture, you can use the models everywhere. So, let’s do it. We create a new project in the solution of the class “Windows Desktop/Class lIbrary” and we call it MoneyBanks.Models.

After that, we can delete the created class in the new project and cut and paste our Bank class to this project. The only thing we have to do, is to fix the namespace name in the class. It should end like this:

namespace MoneyBanks.Models
{

public class Bank
{

public string Name { get; set; }

public string Special1 { get; set; }

public string Special2 { get; set; }

}

}

Of course, now we have to reference this new project from the web application and then, add a reference to that namespace in the MoneyBanks ApiController:

using MoneyBanks.Models;

If we run the application now, we won’t see any difference with the all-in-one template application we had before.

Now we are going to force a problem.

Let’s say, our application is about banks, but about different type of banks, we already created the webapi for the money banks, and now we want to create a new webapi for blood banks.

Let’s start adding a controller for that. As we did previously, no difference but the name used. This time, we are going to call this controller “BloodBanksController”.

Let’s change the class used in this controller. If you compare this controller with the other one, they look the same…

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace HelpPageErrorSimulator.Controllers
{

public class BloodBanksController : ApiController
{

// GET: api/BloodBanks
public IEnumerable&lt;Bank&gt; Get()
{
return new Bank[] { new Bank(), new Bank() };
}

// GET: api/BloodBanks/5
public string Get(int id)
{
return "value";
}

// POST: api/BloodBanks
public void Post([FromBody]Bank value)
{

}

// PUT: api/BloodBanks/5
public void Put(int id, [FromBody]Bank value)
{

}

// DELETE: api/BloodBanks/5
public void Delete(int id)
{

}

}

}

As before, we have in red the inexistent class, so, let’s create it. To do that, we are going to create a new class library project called BloodBanks.Models. Then, we changed the automatically created class1.cs by this code:

namespace BloodBanks.Models
{

public class Bank
{

public string Name { get; set; }

public string Special3 { get; set; }

public string Special4 { get; set; }

}

}

As you can see, the only difference with the “other” Bank class, is the namespace and a couple of properties with different name. Now we can go back to the controller project, add a reference to this new project, and add a new using class to the controller:

using System.Collections.Generic;
using System.Web.Http;
using BloodBanks.Models;
namespace HelpPageErrorSimulator.Controllers
{

public class BloodBanksController : ApiController
{

// GET: api/BloodBanks
public IEnumerable&lt;Bank&gt; Get()
{
return new Bank[] { new Bank(), new Bank() };
}

// GET: api/BloodBanks/5
public string Get(int id)
{
return "value";
}

// POST: api/BloodBanks
public void Post([FromBody]Bank value)
{

}

// PUT: api/BloodBanks/5
public void Put(int id, [FromBody]Bank value)
{

}

// DELETE: api/BloodBanks/5
public void Delete(int id)
{

}

}

}

Now run the application in the help page.

HelpPage with 2 apis

 

 

 

 

 

 

 

 

Everything seems to be working fine, right? Well, click on any method and it should raise an exception (A model description could not be created. Duplicate model name ‘Bank’ was found for types ‘MoneyBanks.Models.Bank’ and ‘BloodBanks.Models.Bank’. Use the [ModelName] attribute to change the model name for at least one of the types so that it has a unique name.):

Error

 

 

 

 

 

 

The problem is that the help page creator is finding a collision between the two classes that have the same name.

The Solutions

First Solution

What the error is telling you, is that you need to use the [ModelName] attribute in, at least, one of the classes, naming it differently to avoid the collision. Well, we can do it in our solution, but it won’t work. Let’s try, let’s modify, for instance, the first Bank class to add that attribute:

namespace MoneyBanks.Models
{

[ModelName("MoneyBank")]
public class Bank
{

public string Name { get; set; }

public string Special1 { get; set; }

public string Special2 { get; set; }

}

}

Well, it will never find the ModelName attribute, because it’s implementation is inside the web application project, inside the help area, so, if we reference that project, it will cause a circular reference problem.

We can avoid it by creating a new project in the solution. The target of this new project is to have the help pages module inside.

So, let’s create a new class library project called HelpPageErrorSimulator.HelpArea. Once it is created, let’s make some surgery to the Web project and the new project:

  • Create a folder in the HelpPageErrorSimulator.HelpArea called Areas.
  • Create a folder in the HelpPageErrorSimulator.HelpArea, inside the Areas folder, called HelpPage.
  • Move everything in the Web project under the folder Areas/HelpPage to the recent created folder of the secondary project, EXCEPT the Views folder and the HelpPage.css file.

If we try to build the solution now, we will see that obviously we need to add some references to the new project, those are:

System.ComponentModel.DataAnnotations

System.Runtime.Serialization

System.Web

System.Web.Helpers

System.Web.Http

System.Net

System.Net.Http

System.Net.Http.Formatting

Then, we have to add these packages to the new project, as we did before, using the Package Manager Console:

Install-Package Microsoft.AspNet.Mvc -Version 5.2.3

Install-Package Microsoft.AspNet.WebApi.Client

Install-Package Microsoft.AspNet.WebApi.Core

Install-Package Newtonsoft.Json -Version 6.0.8

Install-Package Microsoft.AspNet.WebApi.WebHost -version 5.2.3

After adding all these references, we will be able to build the new project. Now, in order to have all working, we need to add a reference to this new project in our web application and a reference to this new project to the MoneyBanks.Models project.

Then, edit the MoneyBanks.Models.Bank class and add a using clause, it will end like this:

using HelpPageErrorSimulator.Areas.HelpPage.ModelDescriptions;
namespace MoneyBanks.Models
{

[ModelName("MoneyBank")]
public class Bank
{

public string Name { get; set; }

public string Special1 { get; set; }

public string Special2 { get; set; }

}

}

As you can see, the ModelName attribute is not in red, so, we have done things well.

It’s time to run the application again.

If you click on the first method link of the MoneyBank API, now you can see that the help is working and it shows you a link to your “Named” model MoneyBank, instead of the real name of the class.

You can see the full project from GitHub here:

https://github.com/victorxata/HelpPageErrorSimulator/tree/master

Second Solution

What the error is telling you, is that you need to use the [ModelName] attribute in, at least, one of the classes, naming it differently to avoid the collision. If you do it, as we show in the first solution, you will see a different name of the Bank class in your help. It might not be what you want, as the name of the class may be important. I think that the best solution is to add to the help system, the entire namespace of the class, this way, we don’t have the same name in different classes and, then, we avoid the problem.

Also, with this solution, we don’t need to add the ModelName attribute to any class.

To do it, we need to change some classes in the original help system to use, instead of the name of the class, the FULLNAME of the class that has the complete namespace.

We need to change this classes:

ModelNameHelper

HelpPageSampleGenerator

Replace, in ModelNameHelper, the content of the class with this:

using System;
using System.Globalization;
using System.Linq;
using System.Reflection;

namespace HelpPageErrorSimulator.Areas.HelpPage.ModelDescriptions
{

internal static class ModelNameHelper
{
// Modify this to provide custom model name mapping.

public static string GetModelName(Type type)
{
ModelNameAttribute modelNameAttribute = type.GetCustomAttribute&lt;ModelNameAttribute&gt;();
if (modelNameAttribute != null &amp;&amp; !String.IsNullOrEmpty(modelNameAttribute.Name))
{
return modelNameAttribute.Name;
}

string modelName = type.FullName;

if (type.IsGenericType)
{
// Format the generic type name to something like: GenericOfAgurment1AndArgument2
Type genericType = type.GetGenericTypeDefinition();
Type[] genericArguments = type.GetGenericArguments();
string genericTypeName = genericType.FullName;
// Trim the generic parameter counts from the name
genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`'));
string[] argumentTypeNames = genericArguments.Select(t =&gt; GetModelName(t)).ToArray();
modelName = String.Format(CultureInfo.InvariantCulture, "{0}Of{1}", genericTypeName, String.Join("And", argumentTypeNames));

}

return modelName;

}

}

}

As you can see if you compare, the changes I’ve made are simple, I changed the type.Name by type.FullName and genericType.Name by genericType.FullName (not really necessary this last one).

This way, instead of getting the name of the class, the system will get the full name, including the namespace.

Replace, in HelpPageSampleGenerator, the method WriteSampleObjectUsingFormatter with this one:

[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded as InvalidSample.")]
public virtual object WriteSampleObjectUsingFormatter(MediaTypeFormatter formatter, object value, Type type, MediaTypeHeaderValue mediaType)
{

if (formatter == null)
{
throw new ArgumentNullException("formatter");
}

if (mediaType == null)
{
throw new ArgumentNullException("mediaType");
}

object sample = String.Empty;
MemoryStream ms = null;
HttpContent content = null;

try
{
if (formatter.CanWriteType(type))
{
ms = new MemoryStream();
content = new ObjectContent(type, value, formatter, mediaType);
formatter.WriteToStreamAsync(type, value, ms, content, null).Wait();
ms.Position = 0;
StreamReader reader = new StreamReader(ms);
string serializedSampleString = reader.ReadToEnd();
if (mediaType.MediaType.ToUpperInvariant().Contains("XML"))
{
serializedSampleString = TryFormatXml(serializedSampleString);
}
else if (mediaType.MediaType.ToUpperInvariant().Contains("JSON"))
{
serializedSampleString = TryFormatJson(serializedSampleString);
}
sample = new TextSample(serializedSampleString);
}
else
{
sample = new InvalidSample(String.Format(
CultureInfo.CurrentCulture,
"Failed to generate the sample for media type '{0}'. Cannot use formatter '{1}' to write type '{2}'.",
mediaType,
formatter.GetType().FullName,
type.FullName));
}
}
catch (Exception e)
{
sample = new InvalidSample(String.Format(
CultureInfo.CurrentCulture,
"An exception has occurred while using the formatter '{0}' to generate sample for media type '{1}'. Exception message: {2}",
formatter.GetType().FullName,
mediaType.MediaType,
UnwrapException(e).Message));
}
finally
{
if (ms != null)
{
ms.Dispose();
}
if (content != null)
{
content.Dispose();
}
}

return sample;
}

If you take a look at the code, I have done exactly the same here, instead of formatter.GetType().Name, I’ve written formatter.GetType().FullName and instead of type.Name I’ve written type.FullName.

After done that, you can run the application showing the help page and, if you click on a link, you will see, instead of the name of the class, the full namespace of the class:

Full namespace

 

 

 

 

 

 

 

And that is everything. Now the help system will work even with classes with the same name in different namespaces.

You can see the full project from GitHub here:

https://github.com/victorxata/HelpPageErrorSimulator2/tree/Master1

I hope this helps you in your projects.

MongoDb .Net Series (III)


(Serie I)

(Serie II)

mongoDB-net.fw

 

En el anterior capítulo nos quedamos a punto de saber la diferencia entre una colección de MongoDb y una tabla de un gestor de SQL.

Bien, como ya sabéis, MongoDb es un gestor de bases de datos no relacionales o NoSql.

Bien, el concepto “no relacional”, implica que los datos no están estructurados, esto es, no tienen ni una estructura definida inicialmente, ni relaciones entre ellos. Esto, que podría parecer un despropósito, proporciona un nivel de velocidad de lectura y escritura desorbitados comparados con un gestor SQL. También permite al programador pensar directamente en objetos completos. Estos objectos completos, en terminología Mongo, se llaman Documentos.

Los documentos pueden tener las propiedades que se quiera, de hecho, pueden convivir en el mismo grupo o colección, documentos con diferente número y nombre de campos, a Mongo no le importa. Pues bien, ahí está, una colección, es un grupo de documentos. Si pensaramos en SQL, sería una tabla, pero con la rigidez del sistema, es decir, todos los registros tienen que tener el mismo número, nombre y tipo en los campos, hay campos obligatorios, etc. En una colección de Mongo, no existen estas restricciones. Piensa un momento en el follón que tienes que organizar cada vez que añades un campo en la base de datos. Pues en Mongo este follón se reduce a la mínima expresión.

Bien, después del rollo, vamos a ver un ejemplo. Como ya he dicho, un documento es un conjunto de propiedades, si lo pensamos en c#, podríamos asociar este documento a una clase.

Para simplificar el ejemplo, vamos a hacer una pequeña colección de electrodomésticos. Para ello, vamos, en nuestro programa, a definir una pequeña clase llamada Robot y otra pequeña clase llamada Reparación:

public class Robot
    {
        [BsonId(IdGenerator = typeof(CombGuidGenerator))]
        public Guid Id { get; set; }
        public string Nombre { get; set; }
        public string Marca { get; set; }
        public string Modelo { get; set; }
        public DateTime FechaDeCompra { get; set; }
        public bool EnGarantia { get; set; }
        public List<Reparacion> Reparaciones { get; set; } 
    }

    public class Reparacion
    {
        public DateTime Fecha { get; set; }
        public string Tecnico { get; set; }
        public string Descripcion { get; set; }
        public decimal Precio { get; set; }
    }

Como puedes ver, hemos añadido un atributo encima de la propiedad Id, esto va a hacer que auto-genere un Id.

Ahora vamos a decirle a nuestro programa que añada un robot a nuestra colección de Robots. Claro, te preguntarás, ¿pero ya?, ¿ya puedo insertar registros? La respuesta es sí. Cuando Mongo no encuentra la colección que estas intentando usar, la crea para ti.

Fíjate en como queda el programa:

    class Program
    {
        private const string ConnectionString = "mongodb://mongonetseriesuser:mongonetseriespassword@ds027748.mongolab.com:27748/mongonetseries";
        private const string DatabaseName = "mongonetseries";
        static void Main(string[] args)
        {
            var client = new MongoClient(ConnectionString);
            var server = client.GetServer();
            var database = server.GetDatabase(DatabaseName);

            var robotCollection = database.GetCollection<Robot>("Robots");
            var robot = new Robot
            {
                Marca = "Robotus",
                Modelo = "XS33",
                EnGarantia = false,
                FechaDeCompra = DateTime.Now.AddDays(-120),
                Nombre = "Mi robot",
                Reparaciones = new List<Reparacion>
                {
                    new Reparacion
                    {
                        Tecnico = "Pepe",
                        Descripcion = "No funciona",
                        Fecha = DateTime.Now.AddDays(-12),
                        Precio = 123.59
                    }
                }
            };
            robotCollection.Save(robot);

            Console.WriteLine("Robot salvado en la base de datos");
            Console.ReadKey();
        }
    }

Si te fijas en el código, verás que estamos obteniendo la colección de robots con esta línea:

var robotCollection = database.GetCollection<Robot>(“Robots”);

En ella le indicamos al driver que el nombre de la colección en MongoDb es o será Robots, y que va a almacenar objectos de la clase Robot.

Después puedes ver que simplemente instanciamos un objecto de la clase Robot (que contiene una lista de objetos de la clase Reparacion, y lo guardamos en su colección con la línea:

robotCollection.Save(robot);

Si abres el interfaz web de MongoLab, y miras dentro de la colección, verás que el objecto que nos ha creado es como este:

{
    "_id": {
        "$uuid": "4d603951-80c0-6a97-bf9f-5d0135a3c5b1"
    },
    "Nombre": "Mi robot",
    "Marca": "Robotus",
    "Modelo": "XS33",
    "FechaDeCompra": {
        "$date": "2014-01-24T22:12:45.266Z"
    },
    "EnGarantia": false,
    "Reparaciones": [
        {
            "Fecha": {
                "$date": "2014-05-12T21:12:45.268Z"
            },
            "Tecnico": "Pepe",
            "Descripcion": "No funciona",
            "Precio": 123.59
        }
    ]
}

Como podrás apreciar, se trata de un objeto JSON, concretamente, MongoDb guarda objetos BSON.

Hasta aquí cómo guardar documentos en MongoDb, como ves, es relativamente sencillo. En el próximo número, veremos como obtener esos documentos.

MongoDb .Net Series (II)


 

(Viene de MongoDb .Net Series (I)) (Sigue en MongoDb .Net Series (III))
mongoDB-net.fw

Como prometí en el post anterior, no voy a hablar más de infraestructura, sólo código.

Vamos a empezar por algo sencillo, vamos a crear una aplicación de consola y vamos a conectarnos desde ella a MongoDb.

Para ello, una vez creada tu aplicación de consola, haz click con el botón derecho en las referencias y selecciona “Manage NuGet Packages“.

Vamos a buscar un paquete que se llama, oh sorpresa, MongoDb:

installmongodriver

 

Selecciona el primer paquete de la lista, es decir, el driver oficial de MongoDb para C# y pulsa en Install y luego en I Accept. Cuando el sistema termine de instalar, pulsa en Close.

Si miras ahora la lista de referencias, verás que se te han añadido dos archivos nuevos:

MongoDB.Bson y MongoDB.Driver

Con esto tenemos suficiente para conectarnos a la base de datos que hemos creado en el post anterior.

Editamos nuestro Program con las siguientes líneas:


class Program
{
   private const string ConnectionString = "mongodb://mongonetseriesuser:mongonetseriespassword@ds027748.mongolab.com:27748/mongonetseries";
   private const string DatabaseName = "mongonetseries";
   static void Main(string[] args)
   {
      var client = new MongoClient(ConnectionString);
      var server = client.GetServer();
      var database = server.GetDatabase(DatabaseName);
      var collections = database.GetCollectionNames();
      foreach (var collection in collections)
      {
         Console.WriteLine(collection);
      }
      Console.WriteLine("Fin de lista de colecciones en la base de datos");
      Console.ReadKey();
   }
}

Si ejecutáis el programa, veréis que MongoDb ha creado dos colecciones en la base de datos llamadas:

system.indexes

y

system.users

Y, por el momento, lo dejamos aquí.

Ya sabemos crear una base de datos en la nube en un buen servicio y ya sabemos conectarnos a MongoDb desde .Net y obtener la lista de colecciones de la base de datos.

En el siguiente post, veremos lo que es una colección y su diferencia con una tabla en un sistema de base de datos SQL.

MongoDb .Net Series (I)


 

(Siguiente artículo)

 

Recientemente, en mi compañía hemos empezado un desarrollo nuevo y hemos seleccionado MongoDb como almacén de datos.

Al no tener mucha experiencia en bases de datos no sql, comencé a buscar información en internet, pero me encontré dos problemas: el primero, que no hay mucha documentación sobre desarrollo en MongoDb en castellano (excepto la proporcionada por la propia compañía), y el segundo, que la poca que hay no cubre el desarrollo con .net, se centra en Java, Php o Python.

Estoy acostumbrado (como la mayoría de vosotros supongo) a leer y estudiar en inglés, no es un problema para mí, pero estoy seguro de que hay mucha gente que agradecerá esta serie en castellano.

Dicho esto, al lío.

Vamos a empezar por lo más fácil, que es no tener que instalar la base de datos, para eso ya hay muchos tutoriales. Esta serie de posts se va a centrar en desarrollo puro y duro, no en infraestructura. Aún así, aquí tienes unas pequeñas líneas acerca de cómo crearte una base de datos inicial para seguir el tutorial (si es que así se le puede llamar).

Hay una empresa que proporciona servicio de MongoDb en la nube de manera gratuita, para desarrollo y pruebas es más que suficiente. La empresa se llama MongoLab, y es recomendable que para seguir el código aquí escrito, te registres y des de alta una base de datos.

Registrarse es de lo más sencillo, únicamente haz click en SignUp y rellena tus datos:

mongolabregister

 

 

 

 

Recibirás un correo de confirmación con diversos links para saber como trabajar con su MongoDb-as-a-Service.

Después de registrarte, se te mostrará una pantalla donde tienes un botón para crear una base de datos:

createnewmongolabCuando hagas click en Create New, te aparecerá otra ventana en la que puedes seleccionar:

El proveedor. Yo te recomiendo Windows Azure, pero sólo románticamente, siendo esta una serie de posts sobre .net, la verdad es que cualquier proveedor funciona realmente bien. Si seleccionas Windows Azure, la localización del DataCenter en que puedes seleccionar un nodo gratuito de desarrollo, es EastUS, si seleccionas otro DataCenter, solo tienes opciones de pago.

El Plan. Como ya he indicado, Si seleccionas Azure EastUs, puedes seleccionar Single-node(development), con lo que tendrás disponible una base de datos de hasta 0.5Gb gratis.

El nombre de la base de datos. En mi caso, voy a llamarla mongonetseries (recuerda poner tu nombre en minúsculas).

createdbmongolabDespués, solo tienes que pulsar en Create new MongoDB deployment y el sistema te creará todo lo que necesitas para empezar a utilizar MongoDB en tu aplicación.

 

 

 

 

 

A continuación, tras crear tu base de datos, el sistema te mostrará la lista de bases de datos que tienes, en teoría, sólo una.

Haz click en ella, pues enseguida te mostrará la cadena de conexión que necesitas usar desde tu aplicación.

connstringmongo

 

 

 

 

Y hasta aquí el primer post. Prometo que no volveré a mencionar la infraestructura en el resto de la serie.

 

 

 

 

 

Localize Web Applications with Microsoft MVC. The Ajax part.


As you can read in this post, it is easy to maintain a localized web application with Microsoft MVC.

This quick post is to add functionality to the client side.

Ajax Calls

In this kind of application, it’s usual to add a lot of ajax calls. This ajax calls, used to have an url without the host, something like:


$.ajax({
 type: "GET",
 url: '/ajaxService/dataValues',

...

In our example, this will fail, because the routing system is not finding any match of that pattern.

As we are always using a two characters in the url to set the language to retrieve, it is easy to get this characters from javascript and add them to the url. Note that if there is no language set in the url (default language), the code is setting the language to ‘en’, which is the default language of the site:


var url = '/ajaxService/dataValues';
var path = window.location.pathname.split('/');
var lang = (path[1].length != 2 ? "en" : path[1];
var urlService = '/' + lang + url;
$.ajax({
   type: "GET",
   url:urlService,

   ...

Messages

Another milestone to acquire is the messages showed in the browser. We have all the messages coming from the server in the render already translated, but in a rich client application, many of them will produce in the client side, so, we need a mechanism to show them in the proper language.

We can leverage jStorage to make the hard job. this tool is compatible from IE6!!!, so you will not have problems with browsers, even in mobile browsers.

E.g., if we need to get a string to display into a warning div, we can write a simple function to retrieve the value translated:

function getText(lang, key) {
   var langkey = lang + key;
   var value = $.jStorage.get(langkey);
   if (!value) {
      value = loadKeyFromServer(lang, key);
      $.jStorage.set(langkey, value);
   }
};

And, of course, a function to get through ajax, the translation required in a simple way:

function loadKeyFromServer(lang, key) {
   var urlService = '/' + lang + '/home/GetTranslation?key=' + key;
   $.ajax({
      type: "GET",
      url: urlService,
      data: {},
      contentType: "application/json",
      success: function(data) {
         return data;
      }
   });
};

As you can see, the system is looking for a translation sending the current language and the key to find. In this example, it is necessary to implement an Action called GetTranslation in the Controller called Home, but we are focused only on the client side, so, I left this implementation to you.

With this system, if the translation required is not found on the local storage, it will ask the server for it. This way, we are only storing the data we are using, and we are only asking for the data we need.

The usage of this function can’t be easier, e.g.:


var lang = (path[1].length != 2 ? "en" : path[1];
$(".alert-error").append("<h4>" +  getText(lang, "ERRORTITLE") + "</h4><p>" + getText(lang, "ERRORMESSAGE") + "</p>");

I hope this post will be useful merged with this one.

Designing Evolvable Web APIs with ASP.NET


EvolvableDesigning Evolvable Web APIs with ASP.NET
Harnessing the power of the web
By Glenn Block, Pablo Cibraro, Pedro Felix, Howard Dierking, Darrel Miller

A simple review:

I am a very lucky person because I had the opportunity to read this fantastic book before to roll out. Seriously, anyone who wants to learn how to write a really consistent webapi using the last Microsoft technologies, needs to read this first.

The first part is amazing. If you don’t know a lot about the http protocol, you will love this part. It is easy to understand but not simple. It covers almost everything you will need to write an API … knowing what you are doing.

The second part was an epiphany for me. It covers some topics I always wanted to know in deep, like Basic authentication, how, why and why not, Oauth, how why, where…

As I said, almost everything you need to write consistent WebAPI applications is in this book. Maybe I miss more deep and extensive samples, but I understand this can be another book…

Definitely, i recommend this book.

http://shop.oreilly.com/product/0636920026617.do?sortby=publicationDate