Odi - server-side framework
Tags: javascript, node, typescript, opensource
Published: 2018-12-27 23:58:33

---
title: Odi - server-side framework
published: true
description: Server-side Node.Js framework for building scalable, supportable, enterprise-grade applications using TypeScript
tags: #javascript,#node,#typescript, #opensource
---

## Introduction
Hi guys!

I am currently working on the server-side TypeScript framework. My team already widely use this framework in various e-commerce and ERP projects. Structure and semantic were inspired by other popular frameworks like [Spring](https://spring.io/) and [ASP.NET](https://ASP.NET)[.](https://asp.net/) 


List of main goals:
1. Testable, supportable, scalable
2. Minimalistic, idiomatic, clear
3. Intuitive, readable, understandable
4. Powerful

&#x200B;
Currently, there are a lot of possibilities:
1. Describing routing using controllers and decorators
2. Powerful, full-typed Dependency Injection
3. Incoming data validation (using AJV) with various set of decorators
4. TypeORM integration (Repositories injection, Transactional support using CLS)
5. Extendable JWT-based authentication



All parts of the framework are fully typed and integrated with the whole infrastructure.


For the best performance, under the hood, [Fastify](https://www.fastify.io/) is used. The framework is declarative, but also avoids using decorators were it's possible. So, it's keep everything simple, clean and minimalistic.

## Overview

###Controller
Controllers serve as a simple yet powerful routing mechanism in a minimalistic style.

```typescript
    @Controller('foo') 
    export class FooController extends IController {      
        
        @RoutePatch('{id}')     
        bar(id: string, payload: FooDTO) {         
            ...some updates..          
            return Ok();     
        } 

        @Get index() {
            return 'Foo';
        }
    } 
```

So, as you see, there no need to provide any additional param decorators for injection data from the HTTP request. It's just a small controller overview, there are a lot of other possibilities.You can read more in [docs](https://odi.gitbook.io/core/basics/controller).


###Dependency Injection
Odi has powerful dependency injection mechanism out of the box. 
(Let's imagine that we already have `FooRepository`)

```typescript
    //foo.service.ts
    @Service()
    export class FooService {
​
        @Autowired()
        repository: FooRepository;
​
        public getFoo(id: string) {
            return this.repository.findOne(id);
        }​
    }


    //foo.controller.ts
    @Controller('foo')
    export class OrderController extends IController {
​
        @Autowired()
        fooService: OrderService;
​
        @Get async '{id}' (id: string) {
            const foo = this.fooService.getFoo(id);
            
            if(!foo)
                return NotFound();

            return foo;
        }​
    } 
```

As you can see, all dependencies will be automatically provided to all application components.

Currently, Odi support 3 ways of injection: 
* By constructor
* By property
* By method

Classes that are not Odi components can participate in DI. You can simply define behaviour with preset properties and constructor args.

```typescript

    class Pet {
        ...
    }

​
    define(Pet)
        .set('default', {
            constructorArgs: [...],        
            props: {...},
            type: 'singleton'
        })
        .set('special', {
            constructorArgs: [...],        
            props: {...},
            type: 'scoped'
        });

```
###DTO
It's a common scenario when web server should validate data before processing. DTO can optimize and automate this process.

```typescript
    @Data()
    export class TodoDTO {
​
        @MaxLength(80)
        title: string;
​
        @IsOptional()
        @MaxLength(255)
        desctiption: string;
    
}
```

Then, DTO class should be added as an argument for the controller method

```typescript
    @Controller('todo')
    export class TodoController extends IController {
    
        @Autowired()
        todoService: TodoService;   
         
        @Post async index(payload: TodoDTO) {
            ...
        }​
    }
```
And it's all! Odi will automatically inject the validated request body in this argument. If there are some errors during validation, 400 status code will be sent with errors description.

Odi provides a wide set for DTO description, supporting nested DTOs, arrays, enums and etc.

###To Sum up
It was a small overview of some features. If you interested in more, check the [Docs](https://odi.gitbook.io/core/).

## Coming Soon
1. AOP
2. [GRPC](https://grpc.io/) integration
3. GraphQL
4. CLI
5. OpenAPI
6. and more...


## Links
{% github Odi-ts/odi %}

[Docs](https://odi.gitbook.io/core/)


Also, we aim to support [Deno](https://github.com/denoland/deno) in the future.


##Difference between Nestjs

Basically, there only a few common things with Nestjs: MVC Pattern and declarative style. But there are a lot of differences, like the whole infrastructure, decorators use, dependency injection and many others. To sum up differences:

* Nestjs is heavily using decorators, Odi reduces this usage to the minimum (To keep code clean and readable).
* Odi provides built-in validation out of the box for HTTP data via AJV.
* DI/IoT behavior is very different. There is much more magic in Odi, in few words :)
* Authentication out of the box, that fully integrated with other framework modules.
* Controller and WebSockets processing

In the future, it will be the big difference between all integrations and technologies, as Odi was designed from the beginning in another way than Nest.

In my sight, Nestjs is more about [Spring](https://www.spring.io/), but our framework is more [ASP](https://asp.net/) :)

##P.S
From the beginning, the framework was designed as opensource. I really need your feedback, it's very important for me! 

###P.P.S
My small kitten Nancy asking for stars on github 😄😄
<img style="float: left;"src="https://thepracticaldev.s3.amazonaws.com/i/cn1kw8wols3n60824kr4.png" width="300px" />