Skip to content

Commit

Permalink
feat: add middleware section
Browse files Browse the repository at this point in the history
  • Loading branch information
rsaz committed Mar 6, 2024
1 parent 19edea1 commit 9c74b58
Show file tree
Hide file tree
Showing 26 changed files with 965 additions and 645 deletions.
2 changes: 1 addition & 1 deletion docs/overview/controller.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 5
sidebar_position: 6
---

# Controllers
Expand Down
14 changes: 7 additions & 7 deletions docs/overview/decorators.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 10
sidebar_position: 11
---

# Decorators
Expand Down Expand Up @@ -62,9 +62,9 @@ Here is a list of all parameter decorators available in ExpressoTS, along with t

ExpressoTS is an MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to your support. If you'd like to help, please consider:

- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star тнР the project
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues/new/choose)**
- Share the project with your friends and colleagues
- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star тнР the project
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues/new/choose)**
- Share the project with your friends and colleagues
44 changes: 22 additions & 22 deletions docs/overview/dependencies.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 12
sidebar_position: 13
---

# Dependencies
Expand All @@ -16,37 +16,37 @@ For now, we will keep a vigilant watch on included dependencies, using tools lik

## Utilities (Dev Dependencies)

- @commitlint/cli: Lint commit messages
- @commitLint/config-conventional: Lint commit messages
- @release-it/conventional-changelog: Generate changelog
- dotenv: Loads environment variables from .env file
- husky: Git hooks
- prettier: Code formatter
- eslint: Linting code
- ts-node-dev: Typescript runner
- tsconfig-paths: Resolve paths from tsconfig.json
- @commitlint/cli: Lint commit messages
- @commitLint/config-conventional: Lint commit messages
- @release-it/conventional-changelog: Generate changelog
- dotenv: Loads environment variables from .env file
- husky: Git hooks
- prettier: Code formatter
- eslint: Linting code
- ts-node-dev: Typescript runner
- tsconfig-paths: Resolve paths from tsconfig.json

## Core Packages

- express: Http server framework
- inversify: IoC container
- inversify-binding-decorators: Decorators for inversify
- reflect-metadata: Polyfill for metadata reflection API
- express: Http server framework
- inversify: IoC container
- inversify-binding-decorators: Decorators for inversify
- reflect-metadata: Polyfill for metadata reflection API

## Test

- vitest: Testing framework
- vite: Vitest's requirement
- vitest: Testing framework
- vite: Vitest's requirement

---

## Support the Project

ExpressoTS is an MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to your support. If you'd like to help, please consider:

- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star ⭐ the project
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues/new/choose)**
- Share the project with your friends and colleagues
- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star ⭐ the project
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues/new/choose)**
- Share the project with your friends and colleagues
72 changes: 36 additions & 36 deletions docs/overview/di.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 11
sidebar_position: 12
---

# Dependency Injection
Expand All @@ -10,19 +10,19 @@ Dependency Injection (DI) is a design pattern used in software development that

Here are some of the key benefits of using Dependency Injection:

- Decoupling: DI helps to decouple the components of your application. Instead of components creating the objects they depend upon, these objects are passed in (injected) by a DI framework or container. This means components don't need to know about the inner workings of their dependencies, and dependencies can be swapped out without the component knowing or caring.
- Decoupling: DI helps to decouple the components of your application. Instead of components creating the objects they depend upon, these objects are passed in (injected) by a DI framework or container. This means components don't need to know about the inner workings of their dependencies, and dependencies can be swapped out without the component knowing or caring.

- Testability: DI makes unit testing easier. Because dependencies are injected, you can easily provide mock objects during testing. This allows each unit of code to be tested in isolation, with full control over its dependencies.
- Testability: DI makes unit testing easier. Because dependencies are injected, you can easily provide mock objects during testing. This allows each unit of code to be tested in isolation, with full control over its dependencies.

- Reusable Code: With DI, your classes are typically designed to work with interfaces rather than concrete classes. This means you can reuse the same class in different contexts, with different injected dependencies.
- Reusable Code: With DI, your classes are typically designed to work with interfaces rather than concrete classes. This means you can reuse the same class in different contexts, with different injected dependencies.

- Easier Maintenance and Increased Efficiency: By centralizing the creation of objects, and by reducing the amount of hard-coded class instantiation, maintenance becomes easier. When a class changes, you typically only need to update code in one place.
- Easier Maintenance and Increased Efficiency: By centralizing the creation of objects, and by reducing the amount of hard-coded class instantiation, maintenance becomes easier. When a class changes, you typically only need to update code in one place.

- Configurability: You can configure your application structure externally, typically through XML or similar files. This means you can modify the structure and dependencies of your components without having to modify the code itself.
- Configurability: You can configure your application structure externally, typically through XML or similar files. This means you can modify the structure and dependencies of your components without having to modify the code itself.

- Lifecycles and Scoping: manage the lifecycle of injected objects, and control their scoping (e.g., singleton scope, request scope).
- Lifecycles and Scoping: manage the lifecycle of injected objects, and control their scoping (e.g., singleton scope, request scope).

- Concurrency Management: containers can automatically handle service lifetimes in a concurrent environment, which can be a complex task to handle correctly without such a tool.
- Concurrency Management: containers can automatically handle service lifetimes in a concurrent environment, which can be a complex task to handle correctly without such a tool.

In conclusion, DI is a technique that facilitates loose coupling, increased testability, and more maintainable and flexible code.

Expand All @@ -36,26 +36,26 @@ Here is how ExpressoTS implements DI:

Here is a breakdown of the DI components used in ExpressoTS:

| Components | Description |
| ------------ | ------------------------------------------------------------------------------------------------- |
| Container | The DI container of the ExpressoTS application. |
| Module | A container module is typically used to group related controllers and their dependencies together. |
| Controller | Primary interface between the client and server. Responsible to handle incoming requests. |
| Classes | Any other class part of the ExpressoTS ecosystem, for example, providers, entities, helpers, etc. |
| Components | Description |
| ---------- | -------------------------------------------------------------------------------------------------- |
| Container | The DI container of the ExpressoTS application. |
| Module | A container module is typically used to group related controllers and their dependencies together. |
| Controller | Primary interface between the client and server. Responsible to handle incoming requests. |
| Classes | Any other class part of the ExpressoTS ecosystem, for example, providers, entities, helpers, etc. |

### Resume

- Container have its default scope that can be override by the module. The default scope is `Request` scope.
- Defining a scope for a module forces all controllers under that module to have the same scope.
- Not defining a scope for a module allow controllers to have their own scope using `@scope()` decorator.
- All other registered classes such as providers, entities, helpers can have their specific scope based on the decorator used.
- Decorators:
- Container have its default scope that can be override by the module. The default scope is `Request` scope.
- Defining a scope for a module forces all controllers under that module to have the same scope.
- Not defining a scope for a module allow controllers to have their own scope using `@scope()` decorator.
- All other registered classes such as providers, entities, helpers can have their specific scope based on the decorator used.
- Decorators:

| Decorator | Description |
| ------------------ | ------------------------------------------------------------------------------ |
| @provide | Binds a class to a dependency injection container as RequestScope. |
| @provideSingleton | Binds a class to a dependency injection container as Singleton. |
| @provideTransient | Binds a class to a dependency injection container as Transient. |
| Decorator | Description |
| ----------------- | ------------------------------------------------------------------ |
| @provide | Binds a class to a dependency injection container as RequestScope. |
| @provideSingleton | Binds a class to a dependency injection container as Singleton. |
| @provideTransient | Binds a class to a dependency injection container as Transient. |

### Container

Expand Down Expand Up @@ -85,40 +85,40 @@ Example of usage:

```typescript
@provide(MyRequest)
class MyRequest { }
class MyRequest {}
```

#### Singleton

```typescript
@provideSingleton(MySingleton)
class MySingleton { }
class MySingleton {}
```

#### Transient

```typescript
@provideTransient(MyTransient)
class MyTransient { }
class MyTransient {}
```

:::tip
To define scope bindings the enum BindingScopeEnum can be used.
:::

- `BindingScopeEnum.Singleton` - The dependency will be created once and will be shared across all requests.
- `BindingScopeEnum.Request` - The dependency will be created once per request.
- `BindingScopeEnum.Transient` - The dependency will be created every time it is requested.
- `BindingScopeEnum.Singleton` - The dependency will be created once and will be shared across all requests.
- `BindingScopeEnum.Request` - The dependency will be created once per request.
- `BindingScopeEnum.Transient` - The dependency will be created every time it is requested.

---

## Support the project

ExpressoTS is an MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to your support. If you'd like to help, please consider:

- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star ⭐ the project
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues/new/choose)**
- Share the project with your friends and colleagues
- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star ⭐ the project
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues/new/choose)**
- Share the project with your friends and colleagues
76 changes: 37 additions & 39 deletions docs/overview/entities.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 9
sidebar_position: 10
---

# Entities
Expand All @@ -15,17 +15,17 @@ Here a simple example of an entity User and it's properties:
```typescript
@provide(User)
class User {
private id: string;
public name: string;
public email: string;
private id: string;
public name: string;
public email: string;

constructor() {
this.id = uuidv4();
}
constructor() {
this.id = uuidv4();
}

get Id(): string {
return this.id;
}
get Id(): string {
return this.id;
}
}
```

Expand All @@ -51,8 +51,7 @@ If your entity has dependencies, you can inject them using the `@inject` decorat
```typescript
@provide(User)
class User {

constructor(@inject("logger") private logger: Logger) {}
constructor(@inject("logger") private logger: Logger) {}
}
```

Expand All @@ -63,10 +62,10 @@ Avoid marking constructors with primitive parameters as injectable. This is beca
```typescript
@provide(User)
class User {
name: string;
constructor(name: string) {
this.name = name;
}
name: string;
constructor(name: string) {
this.name = name;
}
}
```

Expand All @@ -78,11 +77,11 @@ In many dependency injection (DI) systems, including InversifyJS, the DI contain

Here are some of the reasons why constructors with primitive parameters can be problematic in DI:

- Ambiguity: If a class has a constructor that requires primitive types, the DI container won't know what values to inject. For example, if a class requires a number in its constructor, the DI container doesn't know what this number represents and what value it should have.
- Ambiguity: If a class has a constructor that requires primitive types, the DI container won't know what values to inject. For example, if a class requires a number in its constructor, the DI container doesn't know what this number represents and what value it should have.

- Inflexibility: A primitive value in the constructor implies that the value is a fixed part of the class. However, DI is often used to manage interchangeable parts of an application (e.g., different implementations of an interface).
- Inflexibility: A primitive value in the constructor implies that the value is a fixed part of the class. However, DI is often used to manage interchangeable parts of an application (e.g., different implementations of an interface).

- Non-descriptive: Primitive values are often non-descriptive and can lead to confusing code. For example, a constructor that takes two string parameters might raise questions like: What do these strings represent? Are there any specific formats or constraints on these strings?
- Non-descriptive: Primitive values are often non-descriptive and can lead to confusing code. For example, a constructor that takes two string parameters might raise questions like: What do these strings represent? Are there any specific formats or constraints on these strings?

## Entity proper injection

Expand All @@ -93,31 +92,30 @@ Here is an example of a factory:
```typescript
@provide(User)
class User implements IEntity {
public id: string;
public name!: string;
public email!: string;
public id: string;
public name!: string;
public email!: string;

constructor() {
this.id = randomUUID();
}
constructor() {
this.id = randomUUID();
}
}

interface IUserFactory {
create(name: string, email: string): User;
create(name: string, email: string): User;
}

@provide(UserFactory)
class UserFactory implements IUserFactory {
create(name: string, email: string): User {
const user = new User();
user.name = name;
user.email = email;
return user;
}
create(name: string, email: string): User {
const user = new User();
user.name = name;
user.email = email;
return user;
}
}

export { User, UserFactory };

```

Now `UserFactory` can be easily injected into other classes.
Expand All @@ -130,9 +128,9 @@ As mentioned above, there are several other approaches, as long as you remain st

ExpressoTS is an MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to your support. If you'd like to help, please consider:

- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star ⭐ the project
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues/new/choose)**
- Share the project with your friends and colleagues
- Become a **[sponsor on GitHub](https://github.com/sponsors/expressots)**
- Follow the **[organization](https://github.com/expressots)** on GitHub and Star ⭐ the project
- Subscribe to the Twitch channel: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)**
- Join our **[Discord](https://discord.com/invite/PyPJfGK)**
- Contribute submitting **[issues and pull requests](https://github.com/expressots/expressots/issues/new/choose)**
- Share the project with your friends and colleagues
Loading

0 comments on commit 9c74b58

Please sign in to comment.