Our journey towards serverless

Recently we were working on a ticket booking and booking cancelation feature in our Fitradar solution. In our solution the booking process consists of two steps: the place reservation in a sport event and payment. And in case the user for some reason didn’t make a payment the system should execute one more step – cancel the reservation. The process becomes non trivial when each step is done in separate environments – the reservation is done on the back-end, but the payment is done on the client’s device. The most challenging part was to figure out how to cancel the reservation in cases when payment was not made or failed.

So we started to look for possible solutions. Initially we were considering Background tasks with hosted services but we didn’t like the fact that the background task will be in the same process as our main back-end service and we have to make sure the process doesn’t shut down after the request is handled. And since we were using the Azure Cloud for hosting our beck-end services the next thing we started to look at was the WebJob which seemed a very good solution for our use case until we introduced ourselves to the Azure Functions. After some investigation we came to conclusion that Azure Service Bus with message deferral and Azure Functions would be perfect solution. The idea was to send a message to the Service Bus after the user has made a reservation. The Service Bus would deliver the message to our Subscription with 15 minutes delay and our Azure Function would cancel the unpaid booking. In order to receive the scheduled Service Bus message we needed to use Azure Function with Service Bus trigger.

Once we learned more about Azure Functions we decided to use them for other tasks as well that should be done outside the usual request – response pattern. One of such tasks in our solution was User Rating calculation. The task should run on a regular basis every Sunday night. This requirement was perfect job for timer triggered Azure Function.

We started to work on our serverless functions. After the function was scaffolded we started to add our business logic. And since we already had a solid CQRS architecture in place for the main back-end service and for each use case we were creating a separate Command that was using the rest of our infrastructure we wanted to add another Command for reservation cancelation use case, but we faced some .NET Core compatibility issues. Our backend runtime was targeting .NET Core 2.2 version, but our Azure Functions runtime was targeting .NET Core 3.1. Although we could just downgrade our Functions app runtime but the documentation strongly encouraged to use version 3.1, because Function apps that target ~2.0 no longer receives security and other maintenance updates. And so we started to migrate our back-end app to the .NET Core 3.1.

We followed official documentation but still struggled to make our third party libraries work again. The biggest challenge was to find a way how to make to work FluentValidation, MediatR and Swagger together. Once we updated the FluentValidation registration in the Startup file according to the provided documentation it switched off the MediatR Pipeline Behaviors. And once we found a way how to make Pipeline Behaviors work it switched off FluentValidation rules on the Swagger UI page. The Stackoverflow and Google couldn’t help us and we started to experiment with the available settings for FluentValidation and MediatR registration. After several hours of error and trial  we found one setting that made all three libraries work together nice and smooth. Here is the peace of code that made our day:

services.AddMvcCore().AddFluentValidation(fv =>
                {
                    fv.RegisterValidatorsFromAssemblyContaining<PlaceValidator>();
                    fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
                    fv.AutomaticValidationEnabled = false;
                });

Now our Fitradar back-end can really benefit from all ASP.NET Core and Azure Functions provided functionality.

P.S. Visit our website: https://www.fitradar.me/ and join the mailing list. Our app is coming soon.

Fitness and mobile app

Hi ! My name is Dmitrijs Beloborodovs

Fitness become one of the buzzwords along with bitcoin or соvid. The first should eventually stop jumping up and down, the second should go away, yet fitness must stay forever. It is crucial to find a good personal trainer to have a smooth start and keep going for a long time. There is something that might help you with that.

Recently I joined a FitRadar team to help with mobile app development. What is a FitRadar (https://fitradar.me) in a nutshell? Briefly: we bring trainers and audience together. Today, your service must be available via different channels: website, integrated in social media and of course, has its own mobile app. A mobile device knows quite much information about you and your habits: your location, language preferences, your schedule and sometimes even specific health metrics (HealthKit is a good example). In other words, it knows enough to propose you a best fitness trainer or sport community in your area, with respect to your timetable, interest or by your friends recommendation. When you start building something great like this, you want to be sure are are building on solid foundation. Here is the first question you might want to evaluate:

Should I go cross platform or native?

Crossplatform solutions (i.e. Flutter, React Native) might look attractive initially, yet brings problems later: super long polishing to achieve smooth and nice UI/UX to mimic platform (all those bounces and responsiveness, etc) and hard path of integration with platform native hardware (location, calendar, etc). So, for us, answer is go 100% native. Stay tuned to know how well we managed to achieve a primary goal of our mobile app — bring nice experience of finding a sport fo your dreams.

Visit our website: https://www.fitradar.me/ and join the mailing list. Our app is coming soon!

P.S. Source: https://medium.com/@dmi3j/fitness-and-mobile-app-3dca370d8e10

Being unique is not always a good thing

The other day I was reviewing my colleagues’ code. It was back-end code written in C#. I noticed that he introduced a class that is very similar to the structure I was quite sure existing in the .NET base library. I found that structure in Microsoft documentation and we agreed that it is better to use .NET type instead of introducing the same type with a different name. After that occasion, I recalled several other cases when I saw the unique solutions for the problems that could have been solved by well-known pattern or practice. My gut feeling was telling me then that it is not a good idea to introduce your own solution for a problem that is already solved by someone else, but I have never really thought what problems such decision can introduce in the project. And so in this article, I wanted to share some thoughts regarding the widely accepted and unique solutions in software development.

First let’s make it clear that any best practice, framework, algorithm or technology was a unique solution in their time. Then when exactly one or another solution became widely accepted?

  • There are solutions in computer sciences that can be measured, like algorithms. In order to estimate the cost of algorithm calculation Big O notation was introduced. When someone comes up with a new algorithm for common problem, for example sorting, we can simply compare how fast each algorithm solves the problem using big O, and choose the one that meets our criteria. And if the new algorithm beats the old one in performance working on the same data, then it becomes the new standard.
  • But most of the technologies, frameworks, patterns and best practices can not be compared by introducing measurable parameters. Think about programming languages or frameworks. There is noway you can make an unambiguous claim which language or framework is better. Then how to find out what is the best language or framework for the given problem. Let me share a story from my youth that might give some insight how the new solution become widely accepted. I remember the story that was shared by my Assembler class professor at University. He started his computer scientists career when software was written in punch cards and he became very good at writing machine code and later at Assembler. And when the first compilers emerged such as FORTRAN and ALGOL he was very skeptical regarding these new languages and the compiling technology in general, because he didn’t believe that the compilers algorithm is able to produce the same quality machine code as a skilled Assembler developer. And in the fifties and sixties well written assembly code really metered, because every byte was counted and his reasoning at that time was valid. But time passed by the hardware and compilers improved and we see that most of the code even in embedded systems now days is written in high level programming languages. The same story goes for programming paradigms – the business application world started with procedural programming and today it ended with Object oriented programming. In Windows and Mobile apps we started with Forms and Activities and today ended with MVVM. So it looks like for such things as programming languages and frameworks more or less useful criteria that we can use is
    • the amount of time the technology is used,
    • amount of software written using the the particular technology
    • number of developers actively using the particular technology

And still all these criteria are not so reliable as big O for algorithms.

In case of algorithm I think it is quite clear that if there is already an algorithm that solves the problem it is pointless to write your own, unless you can produce better one. In case of frameworks I would follow the same logic – if there is an well known framework that can solve the problem it is much safer to relay on the majorities opinion (although the majority can be wrong) rather than on your own single point of view. Even if the framework or pattern will be rejected in the near future at this moment:

  • it is much more tested than your own solution, and therefore there are much more chances to have a flaw or even bug in your solution than in the widely accepted solution
  • it will be much easier for other developers to work with widely accepted solution than yours, because there is much more documentation and all kind of sorts information about the widely accepted solution than you can ever produce. And this will become crucial when your solution will start to live it’s own live

Visit our website: https://www.fitradar.me/ and join the mailing list. Our app is coming soon.

P.S. We are hiring: http://blog.fitradar.me/we-are-hiring/

We are hiring

We are hiring

FitRadar is a new free app to find the best personal trainer or sports events in your local area, in any sport. Fitness is closer than you think. Coming soon.

Key responsibilities:

– Be part of a FitRadar startup team and actively take part in developing the products

– Develop and maintain application software working with established processes

Job requirements:

– 3-5 years of development experience with Swift

– Ability to write consistent, well-documented code (Clean Code)

– OOP, SOLID principles

– Familiarity with the generic mobile development paradigms, architectures, current trends

– iOS SDK, UIKit, CoreDate, Networking, Multithreading

Personal skills:

– Russian, Latvian and English

– Location: Riga or Latvia

– Analytical thinking and self-driven

Join our team and grow with us as co-founder.

If you are interested, please share your resume:

Let’s keep the distances

In my last article I mentioned that we had cases when we needed to split our back-end application across several processes and as a result we gained more flexibility when we needed to scale the application. This time I want to keep sharing some insights on why we try to keep some parts of the application loosely coupled. This time I wanted to talk about loose coupling at design time when the whole application might run in the single process. According to one of the definitions ”loosely coupled system is one in which each of its components has, or makes use of, little or no knowledge of the definitions of other separate components”. In object oriented paradigm, that we are using to create our Fitradar application, most of the code is spread among various classes and therefore the smallest component that we consider is a class. And since classes are just containers for data and functions then we usually see the loose coupling as a way how to call a function of another class with little information as possible.

The simplest way how to call a method on the other object is to create that object from a class (in Java and C# we do that by new operator) and call the needed method. But it turns out there are many cases when it is undesirable to know the class name of an object or even a specific method name during the design time and therefore there are several methods how to reduce the knowledge of a class we are going to use and a method we are going to call:

  • We can replace a class with an interface or an abstract class and in such way reduce the information about the class to the subset of methods that the other classes are interested in. In Object Oriented programming this is known as Polymorphism and is one of the OOP cornerstones. It is really hard to express how important this OOP feature is. I think back in a day that feature was one of the selling points of OOP that pushed out the procedural programming. The biggest gain of using Polymorphism is a flexibility. Now we are not bound to a single code execution flow, because every function that is presented in the execution flow via interface or abstract class can be replaced with other implementation through the configuration or dynamically during a runtime. This in turn opens whole bunch of new possibilities. And the one I like the most is Unit testing. Now days it is hard to imagine how much work it would require to isolate the piece of code and test it without the interfaces that can be mocked.
  • Sometimes we are interested only in one method of the other class and we don’t want to be bound to single class that implements this method, and we want to replace that method implementation. In order to reduce the knowledge about the other class to single methods signature we can use delegates in C#, functional interfaces in Java, Kotlin or function pointers in C\C++. Not all OOP languages provide such constructs though then we should use more verbose interfaces or abstract classes. A delegate can bee seen as placeholder for a method. And once we start to focus on a method without accompanying class we start to enter the realm of Functional programming where function implementation can be written as lambda expression (anonymous functions) and its return type and arguments can be other functions. The most common areas where the function placeholders are used are events and callbacks. And once Linq came out everyone who got to know this library really started to appreciate lambda expressions
  • In cases where Interfaces and Anonymous methods are not enough to describe dependency, for example we don’t want to restrict a method description in our execution flow with a single signature and want to use different rules to describe the method or a class that contains the method, then we can use Reflection. Although Reflection is very powerful tool that allows to achieve a great flexibility, usually it is not recommended to use because it adds an overhead at runtime and degrades the performance

On the larger scale where components are not anymore single classes but the whole systems the loose coupling further can be achieved by introducing the middle-ware like Queues and Service Buses.

As we can see making a method call something that is not bound to a single implementation opens up a dozen of options how to design and build an application in very flexible way.

P.S. Visit http://fitradar.me/ and join the mailing list!