Friday, September 14, 2018

Microsoft announced ASP.NET Core 2.2

In yesterday’s .Net conference, Microsoft announced ASP.NET Core 2.2 as part of .Net Core 2.2 Preview 2 SDK and Visual Studio 2017 15.9 Preview 2. List of new features looks very interesting. Let's have a gist of those:
  • Template updates: This release includes Bootstrap 4 support in ASP.NET Core Web Project templates as well as in scaffold and is the default version for UI, which gives completely new look.
  • Supports Angular 6 for SPA based templates.
  • Web API related changes are the major improvements in this release and contributes towards much easier and much better Web APIs.
  • HTTP/2 support is added for Kestral.
  • lIIS in-process hosting model is added for IIS for much better performance and reliability.
  • Health checks framework is integrated now to monitor health of APIs and apps.Using this we can make sure that our apps and APIs are live and ready for traffic prone situations.
  • New routing system Endpoint routing was brought in, which takes care of several routing problems and performance issues. 
  • SignalR Java client is added.  

Monday, September 10, 2018

Web API Resource URI construction Practices

Main focus of this article would be on how to make Web API more understandable to the consumers from Resource URI construction point.

In Web API, each resource will have unique identifier. So, one should be very careful while constructing these URIs. Here are the few very good practices one should go for:

URI should belong to NOUN rather than ACTIONS.
URI example
Is preferred?
Remarks
api/getemployees
×

api/employees
Using GET
api/id/employees
×

api/employees/{id}
Fetch employee with a given ID using GET
api/xyz/xyz/employees
×

api/employees

api/employees/orderby/name
×

api/employees?orderby=name
Filter criteria

Should Nouns be Pluralize or not?
It is up to you whether you want to go for pluralize nouns or not. But whatever decision you are making it should be consistent throughout the controllers and actions.

IDs should be integer or string? 
One point to remember here is, resource URI construction has nothing to do with the way data is stored at backend. REST API has nothing to do with data storage mechanisms. In other words, if backend is changing over time, URI must not change. 

For example, Today you are using SQL server database with auto incremented integer key as an ID. Now, what if I suddenly planned to move to Mongo DB. Will I go ahead and change my URIs to accommodate ID as a string? Certainly not. 

Best solution for this – GUID. GUID can be used as a primary key in any database, which will provide more flexibility while changing the backend database keeping the resource URI intact. GUID will also help us to hide underlying technology.

Disclaimer
Please note, all the points mentioned above are just the guidelines and by following these we can end up with good URI design.

Monday, September 3, 2018

Generating documentation for Web API 2.0

In my previous article, we got the gist of Web API but we didn’t do anything on documentation part. So, in this article we will cover the documentation of our Wep API which will help the users using Swagger.

What is Swagger?
Swagger is a standard which is used to define the API, so that endpoints can be found and discovered easily with the help of small documentation along with the user interface. If it is clear that what API is doing, one can easily consume these APIs. It is similar to WSDL for Web Services.
How to get Swagger?
Swagger is an open source library with a name SwashBuckle and can be taken by any means of importing packages. Let’s have a look on how to get it from Nuget:









What code changes are required?
First of all, we have to go and register the service for swagger as:
public void ConfigureServices(IServiceCollection services)
{ services.AddMvc(); services.AddSwaggerGen(options=> {
options.SwaggerDoc("Version 1", new Swashbuckle.AspNetCore.Swagger.Info { Title = "Conference Planner", Description = "This holds methods to perform CRUD operation using in-memory database." });
});
services.AddDbContext<ApplicationDbContext>(context => { context.UseInMemoryDatabase("ConferencePlanner"); });
        }
Next, we must do configuration related changes along with enabling the user interface for us. This can be done as:
       
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{ app.UseDeveloperExceptionPage();
            }
app.UseSwagger();
app.UseSwaggerUI(swag =>
{
swag.SwaggerEndpoint("/swagger/version1/swagger.json", "Conference Planner APIs");
            });
app.UseMvc();
}
We are almost there. Now quickly build and run the application with an URL as http://localhost:3394/swagger/Version1/swagger.json. Please note, for you it can be different port number. Once the page is loaded, you can see the generated JSON as:







Above JSON contains all the information which is required for any consumer.

Last but not the least, the UI part. To view the UI, URL has to be changed slightly as http://localhost:3394/swagger/













And we are done with SwashBuckle, which is an implementation of Swagger. Happy learning.

Wednesday, August 15, 2018

CRUD operations using ASP.NET Core 2.0 and In-memory database with Entity Framework

In this article, we will create a Web API with in-memory database using Entity Framework and ASP.NET Core 2.0 without any theoretical explanation. To know more on concepts and theory, my previous articles can be referred.

Let’s quickly create a new ASP.NET Core application by choosing API template and name it as ConferencePlanner. Add a new Model entity named Workshop inside a newly add Models folder as shown below:
public class Workshop
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Speaker { get; set; }
}
Here we are going to use in-memory class along with EF. So, we have to add a new class for setting up the database context as shown below:
public class ApplicationDbContext:DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> context):base(context)
    {
    }
}
Now we have to maintain multiple workshops under a conference. So, go ahead and add a DBSet in ApplicationContext class:
       
public DbSet<Workshop> Workshops { get; set; }       
 
Next is to register the DBContext with our application. So, add the below code in Startup.cs class:
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
   services.AddDbContext<ApplicationDbContext>(context => { context.UseInMemoryDatabase("ConferencePlanner"); });
}
Now we will add an Empty Controller using scaffolding options and name it as WorkshopController. Here we also have to associate database context with this controller. So, let’s associate the database context as shown below with some dummy data in it.
public class WorkshopController : Controller 
{
    private ApplicationDbContext _context; 
    public WorkshopController(ApplicationDbContext context)
    {
      _context = context;
       if (!_context.Workshops.Any()) 
       {
         _context.Workshops.Add(new Workshop 
                  { Name = "Event Management", Speaker = "Shweta"});
         _context.SaveChanges(); 
       }
    }
}
Let's add our first method to get a list of all workshops by adding below code:
[HttpPost]
public IEnumerable<Workshop> GetWorkshops(){return _context.Workshops; } 
Now before proceeding further, let’s quickly build the application and run it. Verify that it is working fine as expected.

[{"id":1,"name":"Event Management","speaker":"Shweta"}]

Now our base setup is ready. We can add add the CRUD operations. Let’ go ahead and add those.
[HttpPost]
public IActionResult AddWorkshop(Workshop workshop)
{
       if (workshop == null)
            return BadRequest();
       _context.Workshops.Add(workshop);
       _context.SaveChanges();
       return CreatedAtRoute("GetWorkshops", new { id = workshop.Id }, workshop);
}
In above code snippet, CreateAtRoute() method is associating newly added workshop object to exiting list of workshops. So, that it can be read by method GetWorkshops().
[HttpPut("{id}")] // means that this id will come from route
public IActionResult UpdateWorkshopByID(int id, [FromBody]Workshop ws)
{
    if (ws == null || ws.Id != id)
          return BadRequest();
    var workshop = _context.Workshops.FirstOrDefault(i => i.Id == id);
   if (workshop == null)
          return NotFound();
    workshop.Name = ws.Name;
    workshop.Speaker = ws.Speaker;
    _context.Workshops.Update(workshop);
    _context.SaveChanges();
    return new NoContentResult();
}
[HttpDelete]
public IActionResult DeleteWorkshopByID(int id)
{
    var workshop = _context.Workshops.FirstOrDefault(i => i.Id == id);
    if (workshop == null)
         return NotFound();
    _context.Workshops.Remove(workshop);
    _context.SaveChanges();
    return new NoContentResult();
}
Hope you enjoyed learning CRUD operations.