Saturday, 27 May 2017

Web API 2 Interview FAQs

Web API FAQs:

 

1.       What are the return types of Action methods in Web API?


a.       Void:
If the return type is void, Web API simply returns an empty HTTP response with status code 204 (No Content).

b.      HttpResponseMessage
Web API converts the return value into HttpResponseMessage.
This option also provides the control over response message.
Like you can use server side caching using CacheControlHeaderValue.
response.Headers.CacheControl = new CacheControlHeaderValue()
        {
            MaxAge = TimeSpan.FromMinutes(20)
        };

Also you can use Request.CreateResponse() method to pass a domain model that is serialized using media formmatter based on Content Negotiation.

public HttpResponseMessage Get()
{
    // Get a list of products from a database.
    IEnumerable<Product> products = GetProductsFromDB();

    // Write the list to the response body.
    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, products);
    return response;
}

c.       IHttpActionResult
Introduce in Web API2.
It has one method called ExecuteAsync().
public interface IHttpActionResult
{
    Task<HttpResponseMessageExecuteAsync(CancellationToken cancellationToken);
}
It is used to create a factory of HttpResponseMessage . Basically   you can put your logic for HttpResponse in separate classes.
public class TextResult : IHttpActionResult
{
    string _value;
    HttpRequestMessage _request;

    public TextResult(string valueHttpRequestMessage request)
    {
        _value = value;
        _request = request;
    }
    public Task<HttpResponseMessageExecuteAsync(CancellationToken cancellationToken)
    {
        var response = new HttpResponseMessage()
        {
            Content = new StringContent(_value),
            RequestMessage = _request
        };
        return Task.FromResult(response);
    }
}
Example controller
public class ValuesController : ApiController
{
    public IHttpActionResult Get()
    {
        return new TextResult("hello", Request);
    }
}
Response:
HTTP/1.1 200 OK
Content-Length: 5
Content-Type: text/plain; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT

hello

public IHttpActionResult Get (int id)
{
    Product product = _repository.Get (id);
    if (product == null)
    {
        return NotFound(); // Returns a NotFoundResult
    }
    return Ok(product);  // Returns an OkNegotiatedContentResult
}

d.      Some other type
For other types Web API uses Media formatter and serialize the response return with 200 OK.
A disadvantage of this approach is that you cannot directly return an error code, such as 404. 

2.       What is content negotiation?


Content Negotiation is the process of selecting content representation based request headers. As there are multiple representations/formatter available.
Accept: Which media types are acceptable for the response, such as "application/json," "application/xml," or a custom media type such as "application/vnd.example+xml"
Accept-Charset: Which character sets are acceptable, such as UTF-8 or ISO 8859-1.
Accept-Encoding: Which content encodings are acceptable, such as gzip.
Accept-Language: The preferred natural language, such as "en-us".

The object that serializes the resource is called a media formatter. Media formatters derive from the MediaTypeFormatter class. Web API provides media formatters for XML and JSON, and you can create custom formatters to support other media types.

3.       How to create custom media type formatter?

First you have to create your custom formatter class that should be implement/inherit BufferedMediaTypeFormater class of System.Net.Http.Formatting namespace.
Then use CanReadType and ReadFromStream methods to deserialize data and CanWritetype and WriteToStream methods to serialize data.

4.       What is the difference between ASP.Net MVC routing and Web API routing?

In ASP.Net MVC, action methods selected based on URI however in Web API action methods are selected based on Http Methods. But it is also possible to do MVC based routing in Web API.
Each entry in the routing table contains a route template. The default route template for Web API is "api/{controller}/{id}".
When the Web API framework receives an HTTP request, it tries to match the URI against one of the route templates in the routing table. If no route matches, the client receives a 404 error. For example, the following URIs match the default route:
/api/contacts
/api/contacts/1
/api/products/gizmo1
However, the following URI does not match, because it lacks the "api" segment:
/contacts/1

Once a matching route is found, Web API selects the controller and the action:
·         To find the controller, Web API adds "Controller" to the value of the {controller} variable.
·         To find the action, Web API looks at the HTTP method, and then looks for an action whose name begins with that HTTP method name. For example, with a GET request, Web API looks for an action that starts with "Get...", such as "GetContact" or "GetAllContacts". This convention applies only to GET, POST, PUT, and DELETES methods. You can enable other HTTP methods by using attributes on your controller.
·         Other placeholder variables in the route template, such as {id}, are mapped to action parameters.

1. You can specify the HTTP method with an attribute: AcceptVerbsHttpDeleteHttpGetHttpHeadHttpOptionsHttpPatchHttpPost, or HttpPut.
2. Otherwise, if the name of the controller method starts with "Get", "Post", "Put", "Delete", "Head", "Options", or "Patch", then by convention the action supports that HTTP method.
3. If none of the above, the method supports POST.

5.       What is attribute routing?


Attribute routing uses attributes to define route, it has more control over URI then conventional based routing, however you can use both routing in same project. If you will not provide attribute on actions then it will use conventional based routing.

6.       What is the advantage of conventional routing?


In this, routing templates are defined at single place and the routing rules are applies consistently across all controllers. But conventional routing does not support certain type of URI. Like
Suppose you want orders details of customers whose id is 1. 
Then URL looks like /customers/1/orders

7.       Why Attribute routing?

You can handle above type of situation easily with attribute routing.
[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId{ ... }
Other Benefits are
·         API versioning
You can have multiple versions of your APIs.
/api/v1/products
/api/v2/products
·         Overloaded URI segments
In this example, "1" is an order number, but "pending" maps to a collection.
/orders/1
/orders/pending
·         Multiple Parameters types
In this example, "1" is an order number, but "2013/06/16" specifies a date.
/orders/1
/orders/2013/06/16
[Route ("orders/{orderId}/Customer/{customerId}")]

8.       How to enable Attribute routing?

Use config.MapHttpAttributeRoutes(); in WebApiConfig.cs.

9.       How to migrate Web API  1 to 2.

Replace WebApiConfig.Register(GlobalConfiguration.Configuration); by GlobalConfiguration.Configure(WebApiConfig.Register);  in Application_Start method of Global.asax.

10.   How to apply constraints in routing?

Web API 1:
config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new {id = RouteParameter.Optional},
        constraints: new {id = @"\d+"}
    );
               
Web API 2:
                [Route("users/{id:int}"]
public User GetUserById(int id) { ... }

Some other examples:
{x:regex(^\d{3}-\d{3}-\d{4}$)}
{x:range(10,50)}
{x:long}

11.   How to create custom route constraints?

By implementing IsMatch method of IHttpRouteConstraint in your custom class.
Then you have to register in WebApiConfig.cs like
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var constraintResolver = new DefaultInlineConstraintResolver();
        constraintResolver.ConstraintMap.Add("nonzero"typeof(NonZeroConstraint));

        config.MapHttpAttributeRoutes(constraintResolver);
    }
      }
      You can use like
[Route("{id:nonzero}")]
public HttpResponseMessage GetNonZero(int id) { ... }

12.   How to make route parameter optional?

Assign some value to that parameter.
   public class BooksController : ApiController
   {
    [Route("api/books/locale/{lcid:int=1033}")]
    public IEnumerable<Book> GetBooksByLocale(int lcid{ ... }
}

13.   What is the use of Route Name?

Route name are helpful to generate links.
public class BooksController : ApiController
{
    [Route("api/books/{id}", Name="GetBookById")]
    public BookDto GetBook(int id)
    {
        // Implementation not shown...
    }
    [Route("api/books")]
    public HttpResponseMessage Post(Book book)
    {
        // Validate and add book to database (not shown)
        var response = Request.CreateResponse(HttpStatusCode.Created);

        // Generate a link to the new book and set the Location header in the response.
        string uri = Url.Link("GetBookById"new { id = book.BookId });
        response.Headers.Location = new Uri(uri);
        return response;
    }
    }

14.   What is the route order?

When request comes It search for action in the route order.
Look at each URI segment in the route template. For each segment, order as follows:
·         Literal segments. [Route("details")]
·         Route parameters with constraints. [Route("{id:int}")]
·         Route parameters without constraints. [Route("{customerName}")]
·         Wildcard parameter segments with constraints. [Route("{*date:datetime}")]
·         Wildcard parameter segments without constraints. [Route ("pending"RouteOrder = 1)] due to route order 1 is after details.
·         In the case of a tie, routes are ordered by a case-insensitive ordinal string comparison (OrdinalIgnoreCase) of the route template.