I proud to say that I will be giving a talk on Azure Search, fully managed, cloud-based service that allows developers to build rich search applications using REST APIs, at AzureConf 2014! AzureConf is a community event hosted by Microsoft and it will be streamed live on the 25th of September, 2014.

azureconf_banner_748x200

Here is what AzureConf actually is all about:

On September 25th, 2014, Microsoft will be hosting AzureConf, another free event for the Azure community. This event will feature a keynote presentation by Scott Guthrie, along with numerous sessions executed by Azure community members. Streamed live for an online audience on Channel 9, the event will allow you to see how developers just like you are using Azure to develop robust, scalable applications on Azure. Community members from all over the world will join known speakers such as Michael Collier, Mike Martin, Rick Garibay, and Chris Auld in the Channel 9 studios to present their own inventions and experiences. Whether you’re just learning Microsoft Azure or you've already achieved success on the platform, you won’t want to miss this special event.

As said, the event will be streamed live and you need to register through the AzureConf web site. You should also check out the defined schedule, speakers list and AzureConf 2014 Lanyrd page. 

I wouldn't miss this awesome event. Seriously, add this to your calendars :)

Microsoft Turkey Summer School 2014 - ASP.NET Web API and SignalR Talk

In context of Microsoft Turkey Summer School 2014, I had a chance to give a talk on ASP.NET Web API and ASP.NET SignalR a few days ago at Microsoft Turkey Office. Here is the slides, recording video and references from the talk.
2014-08-17 12:04
Tugberk Ugurlu




I have been designing HTTP APIs (Web APIs, if you want to call it that) for a fair amount of time now and I have been handling the HTTP DELETE operations the same way every time. Here is a sample.

HTTP GET Request to get the car:

GET http://localhost:25135/api/cars/3 HTTP/1.1
User-Agent: Fiddler
Accept: application/json
Host: localhost:25135

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Wed, 25 Jun 2014 12:36:48 GMT
Content-Length: 68

{"Id":3,"Make":"Make3","Model":"Model1","Year":2009,"Price":67437.0}

HTTP DELETE Request to delete the car:

DELETE http://localhost:25135/api/cars/3 HTTP/1.1
User-Agent: Fiddler
Accept: application/json
Host: localhost:25135

HTTP/1.1 204 No Content
Date: Wed, 25 Jun 2014 12:36:52 GMT

Now we can see that the car is removed as I received 204 for my HTTP DELETE request. Let's send another HTTP DELETE to same resource.

HTTP DELETE Request to delete the car and receive 404:

DELETE http://localhost:25135/api/cars/3 HTTP/1.1
User-Agent: Fiddler
Accept: application/json
Host: localhost:25135

HTTP/1.1 404 Not Found
Date: Wed, 25 Jun 2014 12:36:52 GMT
Content-Length: 0

I received 404 because /api/cars/3 is not a URI which points to a resource in my system. This is not a problem at all and it's a correct way of handling the case as I have been doing for long time now. The idempotency is also preserved because how many times you send this HTTP DELETE request, additional changes to the state of the server will not occur because the resource is already removed. So, the additional HTTP DELETE requests will just do nothing.

However, here is the question in my mind: what is the real intend of the HTTP DELETE request?

  • Ensuring the resource is removed with the given HTTP DELETE request.
  • Ensuring the resource is removed.

Here is what HTTP 1.1 spec says about HTTP DELETE:

The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully. However, the server SHOULD NOT indicate success unless, at the time the response is given, it intends to delete the resource or move it to an inaccessible location.

A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

I don't know about you but I'm unable to figure out which two of my above intends is specified here. However, I think that the HTTP DELETE request’s intend is to ensure that the resource is removed and cannot be accessible anymore. What does this mean to my application? It means that if an HTTP DELETE operation succeeds, return a success status code (200, 202 or 204). If the resource is already removed and you receive an HTTP DELETE request for that resource, return 200 or 204 in that case; not 404. This seems more semantic to me and it is certainly be more easy for the API consumers.

What do you think?

References



This year, I decided not to miss on awesome developer conference NDC in Oslo and well, I attended! I'm actually still in Norway and I can tell that by looking at my pocket. I'm basically broken in terms of money :) Don't go to conferences if the city is ranked at the top of the World's most expensive cities (kidding, take a loan and go to NDC). If you miss this awesome developer conference, don't worry that much. The videos are already available online and I'm actually watching couple of the ones that I missed.

During the event, a few things were highlighted by many people over and over again which also made sense to me. Since this was a developer conference crowded by the World's top notch software developers, these are worth pointing out as bullet points for developers like me:

  • Mobile matters a lot (kind of obvious but worth highlighting it)!
  • JavaScript is big! No matter what programming language you use and what kind of development you do, it's going to end pretty badly for you if you keep ignoring JavaScript.
  • Learn a functional programming language. If you are a developer, you should (and I should) learn a functional programming language. It's kind of unavoidable in a World where concurrency matters this much.
  • Don't develop for the management, develop for the users of your product and your team mates (current and future).
  • SQL is still there but practically dead (there I said it!).
  • This is only what I felt during these days: you cannot survive in a software industry if you only know one general purpose programming language (well, you probably will but I don't think you will really *survive*. Catching my drift?).
  • Swift (not Taylor Swift) is a joke but it will be loved.

These are just my thoughts during these 3 days and the time will tell us whether those are actually valid points.

Efficiently Streaming Large HTTP Responses With HttpClient

Downloading large files with HttpClient and you see that it takes lots of memory space? This post is probably for you. Let's see how to efficiently streaming large HTTP responses with HttpClient.
2014-05-11 12:56
Tugberk Ugurlu


I see common scenarios where people need to download large files (images, PDF files, etc.) on their .NET projects. What I mean by large files here is probably not what you think. It should be enough to call it large if it’s 500 KB as you will hit a memory limit once you try to download lots of files concurrently in a wrong way as below:

static async Task HttpGetForLargeFileInWrongWay()
{
    using (HttpClient client = new HttpClient())
    {
        const string url = "https://github.com/tugberkugurlu/ASPNETWebAPISamples/archive/master.zip";
        using (HttpResponseMessage response = await client.GetAsync(url))
        using (Stream streamToReadFrom = await response.Content.ReadAsStreamAsync())
        {
            string fileToWriteTo = Path.GetTempFileName();
            using (Stream streamToWriteTo = File.Open(fileToWriteTo, FileMode.Create))
            {
                await streamToReadFrom.CopyToAsync(streamToWriteTo);
            }

            response.Content = null;
        }
    }
}

By calling GetAsync method directly there, we are loading every single byte into memory. You can see this happening in a simple way by opening the Task Manager and observing the memory of the process.

2

We are calling ReadAsStreamAsync on HttpContent after the GetAsync method is completed. This will just get us the MemoryStream, so there is no point there:

Screenshot 2014-05-11 15.18.14

We need a way not to load the response body into memory and have the raw network stream so that we can pass the bytes into another stream without hitting the memory too hard. We can do it by just reading the headers of the response and then getting a handle for the network stream as below:

static async Task HttpGetForLargeFileInRightWay()
{
    using (HttpClient client = new HttpClient())
    {
        const string url = "https://github.com/tugberkugurlu/ASPNETWebAPISamples/archive/master.zip";
        using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
        using (Stream streamToReadFrom = await response.Content.ReadAsStreamAsync())
        {
            string fileToWriteTo = Path.GetTempFileName();
            using (Stream streamToWriteTo = File.Open(fileToWriteTo, FileMode.Create))
            {
                await streamToReadFrom.CopyToAsync(streamToWriteTo);
            }
        }
    }
}

Notice that we are calling another overload of the GetAsync method by passing the HttpCompletionOption enumeration value as ResponseHeadersRead. This switch tells the HttpClient not to buffer the response. In other words, it will just read the headers and return the control back. This means that the HttpContent is not ready at the time when you get the control back. Afterwards, we are getting the stream and calling the CopyToAsync method on it by passing our FileStream. The result is much better:

3

Resources