Request Handling

Actions handle requests getting an instance of the IHttpRequest which gives a comprehensive information about current request. At least it allows to get a request data from the URL or from the message body.

Parameters and Query

To retrieve information from a URL you can use properties Parameters and Query. Both return dynamic object with information from different parts of the URL. The Parameters contains values of named segments of the path while the Query contains values of the query string.

The URL Structure

Next example shows how to extract values from a URL which looks like on previous image.

builder.Get["/{segment1}/{segment2}/{segment3}"] = async request =>
{
    string segment1 = request.Parameters.segment1; // segment1 == "path"
    string segment2 = request.Parameters.segment2; // segment2 == "to"
    string segment3 = request.Parameters.segment3; // segment3 == "resource"

    string key1 = request.Query.key1; // key1 == "value1"
    string key2 = request.Query.key2; // key2 == "value2"

    // ...
};

Form and Content

Such methods as POST, PUT and PATCH can contains the body. Depending on the Content-Type header the message body can be parsed as an object. In this case the Form property returns dynamic object. For instance the request body will be considered as an object if the Content-Type equals application/json (see Media Types).

// curl -X POST -H 'Content-Type: application/json' \
// -d'{"Title":"Title1","Content":"Content1"}' \
// http://www.example.com:80/articles

builder.Post["/articles"] = async request =>
{
    string title = request.Form.Title; // title == "Title1"
    string content = request.Form.Content; // content == "Content1"

    // ...
};

If you have a strongly typed model you can deserialize it from the request body. For example if the Content-Type equals application/json the deserialization can be performed using IJsonObjectSerializer. The Content property allows you to get a Stream object representing the incoming HTTP body. Also important to note the Content can be used for a custom handling of the request body.

 public class ArticlesHttpService : IHttpService
 {
     private readonly IJsonObjectSerializer _serializer;

     public ArticlesHttpService(IJsonObjectSerializer serializer)
     {
         _serializer = serializer;
     }

     public void Load(IHttpServiceBuilder builder)
     {
         // curl -X POST -H 'Content-Type: application/json' \
         // -d'{"Title":"Title1","Content":"Content1"}' \
         // http://www.example.com:80/articles

         builder.Post["/articles"] = async request =>
         {
             var article = _serializer.Deserialize<Article>(request.Content);

             // ...
         };
     }
 }


 public class Article
 {
     public string Title { get; set; }
     public string Content { get; set; }
 }

Note

Both the Form and the Content can not be used at the same time because they read the same request stream. So if you get the Form the request stream will be read and the Content will poit to the end.

Files

In more complex cases a request can contains one or few files which are available via the Files property. The Files returns an enumerable items of type IHttpRequestFile and each of them allows to get the file name and the file data stream.

 builder.Post["/albums/{id}"] = async request =>
 {
     foreach (IHttpRequestFile photo in request.Files)
     {
         // Do something
     }

     // ...
 };