Vlad's blog

In programming veritas

Components of good Web API client. Part 1.

leave a comment »

There are a lot of posts and guides devoted to the subject of creating Web API, but most of them are focused on server side part. The client code is often covered superficially making impression that this subject is trivial and is not worth discussing. In this post I describe some important aspects of developing Web API client. The example code written in C# but many concepts are language agnostic.

For the sake of illustration let’s consider JIRA like system that allows to create,delete and update projects.

Resource: a collection of projects
Url: http://localhost:54531/api/projects
HTTP methods: GET,POST

Resource: a project
Url: http://localhost:54531/api/projects/{id}
HTTP methods: GET,PUT,DELETE,PATCH

Example:
Url: http://localhost:54531/api/projects
HTTP method: GET

Response:

[
 {
 "id": "a3260d06-4c19-4422-bf36-d2e90bd5c85b",
 "name": "Project 1",
 "state": "InProgress",
 "created": "2018-01-13T13:15Z",
 "updated": "2018-02-14T15:07Z" 
 }
]

Also API must support paging and data shaping.
Example:
Url: http://localhost:54531/api/projects?pageNumber=1&pageSize=20&fields=id,name

First version

If we follow REST approach our API should be focused on resources which are projects. Let’s start from a collection of projects.
Url: http://localhost:54531/api/projects
HTTP methods: GET,POST
First thing you want in your client API is a method for getting a collection of resources. The first version simple returns a list of projects.

public static async Task Test()
{
    List<ProjectDto> projects = await ProjectsResource.Get();
}

class ProjectsResource
{
    public static Task<List<ProjectDto>> Get()
}

class ProjectDto
{
    public ProjectResource This { get; private set; }

    public string Id { get; set; }
    public string Name { get; set; }
    public DateTime Created { get; set; }
    public DateTime Updated { get; set; }
    public ProjectState State { get; set; }

    public enum ProjectState
    {
        NotStarted,
        InProgress,
        Finished
    }
}

Read the rest of this entry »

Advertisements

Written by vsukhachev

January 29, 2018 at 3:09 am

Posted in Development

Tagged with

Don’t use exceptions for validation

leave a comment »

Exceptions are often used for validation. In the code below we check if a name of a customer is already exist in a repository and throw an exception if it is true. The exception is used to pass validation error message.

public Customer AddCustomer(string firstName, string lastName)
{
    if(customers.Any(x => x.FirstName == firstName && x.LastName == lastName))
        throw new Exception($"Failed to add a customer: the customer with this name already exists");

    var customer = new Customer(firstName, lastName);
    customers.Add(customer);

    return customer;
}

The client code is below.

try
{
    Customer customer = repository.AddCustomer("Vlad", "Sukhachev");

    repository.Save();
}
catch (Exception e)
{
    ShowValidationError(e.Message);
}

There are two problems with this approach. First, the signature of AddCustomer is dishonest. In order to realize that this method throws an exception the developer has to review the source code. The second concern is more subtle. By the definition, the exception is used to signal an exceptional situation which is a result of a bug in code. Wrong user input certainly does not fit into this category.

In order to fix this issue we need to use Result class from CSharpFunctionalExtensions. Now the repository code looks like this.

public Result<Customer> AddCustomer(string firstName, string lastName)
{
    if (customers.Any(x => x.FirstName == firstName && x.LastName == lastName))
        return Result.Fail<Customer>($"Failed to add a customer: the customer with this name already exists");

    var customer = new Customer(firstName, lastName);
    customers.Add(customer);

    return Result.Ok(customer);
}

And the client code.

Result<Customer> result = repository.AddCustomer("Vlad", "Sukhachev");

if(result.IsFailure)
    ShowValidationError(result.Error);

repository.Save();

Now when we look at the signature of AddCustomer method we can say that it can return a result indicating failure and we don’t use an exception to pass validation error. That does not mean that we should avoid using exceptions. Even in this simplified example there is a legal case where an exception is relevant. CustomerRepository.Save can raise an exception in case of any database related issue.

Written by vsukhachev

January 20, 2018 at 6:57 pm

Introduction to TPL Dataflow

leave a comment »

TPL Dataflow Library is one of underestimated libraries which have not gained as much popularity as other TPL components. I believe the main reason is a fact that Microsoft did not include Dataflow Library in the .NET Framework 4.5, you should install it separately. Anyway in this post I am going to quickly describe main features of TPL Dataflow and answer a question why and when you need to use this library.

TPL Dataflow Library is designed to help programmers write concurrent enabled applications. You may say that this is what TPL is all about. True, but Dataflow Library is supposed to be used in very specific scenarios. Imagine you are developing an application that has to process many request which is typical scenario for server side applications. And processing of a request involves many concurrent tasks: Web API calls, database transactions, file IO operations, image processing etc. Also you want to be able to control resource utilization in order to keep your server responsive. Certainly, you can do everything described above using TPL tasks, develop own queues for message prioritization and use synchronization primitives to protect shared data. TPL Dataflow provides a programming model that hides low level details of managing concurrent workflows and allows you to focus on your business logic.

Programming Model

The main concept in Dataflow is a block. You can consider a block as data structure that can buffer and process data. Normally your Dataflow application is a collection of linked blocks forming a workflow specific for your needs. Actual communication between blocks is organized in a form of messages passed from one block (source) to another (target). There are different types of blocks: data transform block, buffer block, action block. You can build a simple pipeline which is a linear sequence of blocks or network, which is a graph of blocks.

Common blocks

Transform block

Transform block is used to receive input value and return transformed value. In the example below TransformBlock receives user names and returns user photos.

var photoService = new PhotoService();
var transformBlock = new TransformBlock<string, Photo>(async userName =>
{
 Photo userPhoto = await photoService.GetUserPhoto(userName);

 return userPhoto;
});

Read the rest of this entry »

Written by vsukhachev

March 5, 2017 at 12:32 pm

Posted in Development

Tagged with ,

Web API versioning in real world applications

leave a comment »

Once you have published your API it is set in stone. Customers who use your API expect it to not change. Otherwise their code may fail due to changed contract or behavior. But requirements will change and we need to figure out a way to evolve API without breaking existing clients. So every time when a breaking API change occurs you need to release a new version of API. That does not mean you need to support all versions forever. But you need to get rid of old versions of API with some care so customers have an idea how to move to a newer version of API.
In this post I am going to discuss how Web API versioning affects entire application and provide some recommendations how to organize source code to maintain different versions of API.

Example project can be downloaded here.

Introducing test application

In order to illustrate API versioning strategies we are going to develop a simple Web API for retrieving tasks. A task contains Name, Description, Owner and task state attributes: IsStarted and IsFinished. Each task belongs to particular Project which is barely a container of tasks. Application consists of three layers:

  • Domain layer that includes Task and Project definition
  • Data access layer that defines TaskRepository class. TaskRepository uses domain classes in serialization.
  • Distributes services layer defines DTO’s used by TaskController

versioning-domain

Read the rest of this entry »

Written by vsukhachev

December 12, 2016 at 10:37 am

Posted in Development

Tagged with

OAuth 2 flows: Client flow

leave a comment »

Client flow is used solely for machine to machine communication, i.e. no Resource Owner involved. Client sends client_id and secret to Authorization Server and then receives access_token and refresh_token.

Client.png

This type of flow is usually used when Web application needs to access Web API.

Written by vsukhachev

December 3, 2015 at 2:51 am

Posted in Development

Tagged with

OAuth 2 flows: Resource Owner Credentials flow

leave a comment »

This type of flow is used when Resource Owner trusts the Client. Client might be mobile application, desktop application or browser application communicating with Web server. Device where Client is installed is trusted as well so user name and password can be stored on this device. In this flow Resource Owner enters user name and password in the UI provided by Client. Then Client sends POST request to Authorization server. The request contains entered user name and password.

Resource Owner Credentials Flow-1

Authorization Server responds with access_token and refresh_token.

Resource Owner Credentials Flow-2

access_token is included in each request that Client sends to Resource Server.

Resource Owner Credentials Flow-3

When access_token is expired Client can repeat this procedure, i.e. send user name and password and collect new access token or it can use refresh_token. Ideally Client should not store user credentials. Instead it should ask for user credentials once, collect refresh_token and then use it forever to obtain new refresh_token. access_token and refresh_token might be stored on a device.

Written by vsukhachev

December 3, 2015 at 2:51 am

Posted in Development

Tagged with

OAuth 2 flows: Implicit flow

leave a comment »

Implicit flow is probably the most common scenario. It is used when Client is mobile application (IOS, Android, Windows Phone) or native application or browser mobile application which wants to access resource on the behalf of Resource Owner.

Implicit Flow-1

Resource Server redirects application to Authorization Server. client_id identifies application, redirect_uri specifies Uri where Client will be redirected after authorization completed.

Implicit Flow-2

Then Authorization Server asks user to authorize. Depending on particular implementation (Google, Twitter, Facebook) the login screen might look different.

Google Login Screen

The next step is Consent screen where Resource Owner will be prompted to allow application to perform certain actions.

Google consent screen

When authorization is complete the Authorization Server executes redirect_uri passing access token and expiration interval.

Implicit Flow-3

Notice that access_token and expires_in are specified after pound character which assumes that they never passed to the Resource Server. So Client can extract access_token and include it in the next requests.

Implicit Flow-4

This flow does not use refresh token since this implies that user name and password must be stored on a device which can not be considered as secured. So user should periodically repeat the authorization procedure.

Written by vsukhachev

December 3, 2015 at 2:50 am

Posted in Development

Tagged with