diff --git a/docs/overview/application.md b/docs/overview/application.md index f94e899a..987ddcd5 100644 --- a/docs/overview/application.md +++ b/docs/overview/application.md @@ -8,10 +8,10 @@ The Application Overview provides a comprehensive demonstration of the main comp ![Application Overview](./img/app-overview.png) -ExpressoTS is a web application framework that provides a simple wrapper around popular HTTP servers, including **[Express](https://expressjs.com)**, **[Fastify](https://www.fastify.io/)**, or **[Koa](https://koajs.com/)**. +ExpressoTS is a web application framework that provides a wrapper around popular HTTP servers, including **[Express](https://expressjs.com)** and **[Fastify](https://www.fastify.io/)**. :::info -Currently, only Express has been thoroughly tested by the ExpressoTS team. +Currently, only Express has been thoroughly tested by the ExpressoTS team. Fastify adapter is a work-in-progress. ::: The architecture of an ExpressoTS application is built around the **[Inversify](https://inversify.io/)** IoC container, which is used to identify and inject dependencies into class constructors. This approach allows the IoC container to load all the necessary modules, including their respective routes (controllers). By using use-cases and providers as needed, routers can handle incoming requests. @@ -26,7 +26,7 @@ By leveraging the power of Inversify, ExpressoTS provides a custom Dependency In | Controller | Component responsible for processing requests and responses based on the URL and HTTP method. It also validates the conformity of the incoming data. | | Use Case | Component responsible for implementing the logic required to handle requests received from the controller. When the controller receives an HTTP request and validates the incoming data, it triggers the relevant use case, passing along the validated data for processing. The use case performs the necessary operations based on the request and returns the appropriate response to the controller, which then sends the response back to the client. | | Provider | Component responsible for providing external functionality to the application. | -| Repository | Component responsible for providing layer of communication with the database. Facilitating connection and CRUD operations. | +| Repository | Component responsible for providing layer of communication with the database. Facilitating connection and CRUD operations. | :::info Providers and Repositories are optional components. You can use them if you need to provide extra functionality to your application such as database integration, logging system, authentication, email etc. @@ -45,14 +45,16 @@ ExpressoTS will prevent you from initializing the Application without a controll **_No controllers have been found! Please ensure that you have register at least one Controller._** ::: -## Application Class +## AppExpress Class -The Application class offers a way to create and configure the server, passing **[Express.js middlewares](https://expressjs.com/en/guide/writing-middleware.html)** or other middleware upon server creation. +The AppExpress class offers a way to create and configure the server, passing **[Express.js middlewares](https://expressjs.com/en/guide/writing-middleware.html)** or other middleware upon server creation. -### Application Class Definition +To create an ExpressoTS application instance, we use the `AppFactory` class, which is responsible for creating the application instance and initializing the container, modules, and controllers. The `create()` function returns an IApplicationExpress which provides a set of methods to configure the server, including the `listen()` method, which starts the server and listens for incoming requests. + +### AppExpress Class Definition ```typescript -class Application { +class AppExpress { /** * Configure services that should be initialized before the server starts. */ @@ -66,34 +68,28 @@ class Application { /** * Perform actions or cleanup after the server is shutdown. */ - protected serverShutdown(): void { - process.exit(0); - } + protected serverShutdown(): void {} - public create( + public async create( container: Container, - middlewares: express.RequestHandler[] = [] - ): Application {} + middlewares: Array = [] + ): Promise {} - public listen( + public async listen( port: number, environment: ServerEnvironment, consoleMessage?: IApplicationMessageToConsole - ) {} + ): Promise {} } ``` -:::info -We also provide an instance of the Application class called **AppInstance**, which exposes the create and listen methods to the developer. This is beneficial when you need to quickly create a server without having to create a new class that extends the Application class and access its lifecycle methods. -::: - ### Create Method -The create method allows developers to pass the container and middlewares to the server. To pass middleware you don't need to use `app.use()`, just pass the middleware and its configuration as demonstrated below: +The create method allows developers to pass the container, middlewares and http server adapters to the server. To pass middleware you don't need to use `app.use()`, just pass the middleware and its configuration as demonstrated below: ```typescript async function Bootstrap() { - App.create(container, [ + await AppFactory.create(container, [ express.json(), express.urlencoded({ extended: true }), cors({ @@ -103,9 +99,14 @@ async function Bootstrap() { } ``` +:::info +Adapters are used to create the server. Currently, Express is the only adapter available. Fastify adapter is a work-in-progress. +When you create an application instance, you can pass the adapter as the third parameter. If you don't pass the adapter, Express is used by default. +::: + ### Listen Method -The listen method starts the server and listens for incoming requests. In the listen method, developers can define the port number and server environment, which can be either development, staging, or production. Developers can also set the application name and version to be displayed in the console when the server starts, as shown in the following example: +The `listen()` method starts the server and listens for incoming requests. In the listen method, developers can define the port number and server environment, which can be either development, staging, or production. Developers can also set the application name and version to be displayed in the console when the server starts, as shown in the following example: ```typescript // App listen method @@ -121,21 +122,56 @@ The name and version of your app can be configured via either the .env file or p ### Application Server Environment -For now, this functionality is a work-in-progress. Currently, it displays the environment in the console when the server starts. The colored console message helps developers to quickly identify the environment the server is running on. +This is an enum that defines the server environment. Currently supported environments are development and production. Upon server initialization, the underlying framework will look for the NODE_ENV environment variable and set the server environment accordingly. If the NODE_ENV environment variable is not set, the server environment will be set to development by default. + +Also, in the application provider user can perform conditional logic based on the server environment. + +```typescript +if (this.isDevelopment()) { + // your logic here +} +``` Here are the enum values available for server environments: ```typescript ServerEnvironment.Development; -ServerEnvironment.Staging; ServerEnvironment.Production; ``` -:::caution SPOILER ALERT -The goal of this functionality is to allow developers to load environment variables based on the environment the server is running on. For example, if the server is running on development, load the .env.dev file, if the server is running on staging, load the .env.stg file, etc.. We are also planning to load environment variables from remote sources such as AWS Parameter Store, AWS Secrets Manager, Azure Key Vault, etc.. -::: +## App Class Provider -## Application Lifecycle Hooks +The App class provider is the heart of the opinionated template application. It is responsible for initializing the application and provide functionalities to be configured in the server bootstrapping process. You can make use of the built-in middlewares and providers to configure your application. + +```typescript +class App extends AppExpress { + private middleware: IMiddleware; + private provider: IProvider; + + constructor() { + super(); + this.middleware = container.get(Middleware); + this.provider = container.get(Provider); + } + + protected configureServices(): void { + this.middleware.addBodyParser(); + this.middleware.setErrorHandler(); + } + + protected postServerInitialization(): void { + if (this.isDevelopment()) { + this.provider.envValidator.checkAll(); + } + } + + protected serverShutdown(): void {} +} +``` + +The App class provider offers a set of out-of-the-box middlewares and providers that can be used to configure your application. Explore the `IMiddleware` and `IProvider` interfaces to see what is available. + +## App Class Lifecycle Hooks Another important aspect of the Application class is lifecycle hooks. These hooks allow developers to execute code before, after and on server shutdown. It is important to note that in order to take advantage of these hooks, developers must create an App class extending the Application class and override the methods as needed. The following example shows the life cycle hooks available at the moment: @@ -147,9 +183,7 @@ Another important aspect of the Application class is lifecycle hooks. These hook protected postServerInitialization(): void { } /* Add any service that you want to execute after server is shutdown */ - protected serverShutdown(): void { - process.exit(0); - } + protected serverShutdown(): void { } ``` ### Hooks Execution Order @@ -161,9 +195,8 @@ Another important aspect of the Application class is lifecycle hooks. These hook Below are the scripts used to run, build and test your application. The command column shows NPM as the package manager, but you can use your package manager of choice. - -| Script | Description | Command | -| ---------- | ---------------------------------------------- | ------------------ | +| Script | Description | Command | +| ---------- | ----------------------------------------------- | ------------------ | | build | Build the production bundle in a ./dist folder. | npm run build | | dev | Runs in development watch mode. | npm run dev | | prod | Runs in production mode based on built bundle. | npm run prod | diff --git a/docs/overview/decorators.md b/docs/overview/decorators.md index e88030da..2fe31285 100644 --- a/docs/overview/decorators.md +++ b/docs/overview/decorators.md @@ -10,19 +10,19 @@ Here is a complete list of all decorators available in ExpressoTS as well as a b Decorators available for your classes. -| 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. | -| @injectable | Marks a class as available to be injected. | -| @inject | Marks a class as available to be injected in the constructor of another class. | +| 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. | +| @injectable | Marks a class as available to be injected. | +| @inject | Marks a class as available to be injected in the constructor of another class. | ## Controller Decorators Decorators available for your controllers. -| Decorator | Description | Usage example +| Decorator | Description | Usage example | | ----------- | ------------------------------ | ------------------------------------------------------------ | | @controller | Marks a class as a controller. | @controller("/path", middleware[]) | | @scope | Binds a controller to a scope. | @scope(BindingScopeEnum.Singleton, or Request, or Transient) | @@ -31,30 +31,30 @@ Decorators available for your controllers. Decorators available for your controller methods. -| Decorator | Description | Usage | -| ----------- | ------------------------------------------------------------------ | ---------------------------- | -| @httpGet | Binds a controller method to a GET HTTP verb. | @httpGet("/path") | -| @httpPost | Binds a controller method to a POST HTTP verb. | @httpPost("/path") | -| @httpPut | Binds a controller method to a PUT HTTP verb. | @httpPut("/path") | -| @httpPatch | Binds a controller method to a PATCH HTTP verb. | @httpPatch("/path") | -| @httpHead | Binds a controller method to a HEAD HTTP verb. | @httpHead("/path") | -| @httpDelete | Binds a controller method to a DELETE HTTP verb. | @httpDelete("/path") | -| @httpMethod | Binds a controller method to a specified HTTP verb. | @httpMethod("verb", "/path") | +| Decorator | Description | Usage | +| --------- | --------------------------------------------------- | ------------------------ | +| @Get | Binds a controller method to a GET HTTP verb. | @Get("/path") | +| @Post | Binds a controller method to a POST HTTP verb. | @Post("/path") | +| @Put | Binds a controller method to a PUT HTTP verb. | @Put("/path") | +| @Patch | Binds a controller method to a PATCH HTTP verb. | @Patch("/path") | +| @Head | Binds a controller method to a HEAD HTTP verb. | @Head("/path") | +| @Delete | Binds a controller method to a DELETE HTTP verb. | @Delete("/path") | +| @Method | Binds a controller method to a specified HTTP verb. | @Method("verb", "/path") | ### Parameter Decorators Here is a list of all parameter decorators available in ExpressoTS, along with their description and usage: -| Decorator | Description | Usage -| ------------------------------------ | ------------------------------------------------------ | -------------------------------------------------------- | -| @request() | Injects the Express Request object. | execute(@request() req: Request) -| @response() | Injects the Express Response object. | execute(@response() res: Response) -| @requestParam(paramName?: string) | Injects a parameter from the request URL path. | execute(@requestParam('id') id: string) -| @queryParam(paramName?: string) | Injects a parameter from the request URL query string. | execute(@queryParam('searchTerm') searchTerm: string) -| @requestBody() | Injects the request body payload. | execute(@requestBody() body: MyDTO) -| @requestHeaders(headerName?: string) | Injects a header from the request headers. | execute(@requestHeaders('authorization') auth: string) -| @cookies(cookieName?: string) | Injects a cookie from the request cookies. | execute(@cookies('session') session: string) -| @next() | Injects the Express NextFunction object. | execute(@next() next: NextFunction) +| Decorator | Description | Usage | +| ----------------------------- | ------------------------------------------------------ | ------------------------------------------------ | +| @request() | Injects the Express Request object. | execute(@request() req: Request) | +| @response() | Injects the Express Response object. | execute(@response() res: Response) | +| @param(paramName?: string) | Injects a parameter from the request URL path. | execute(@param('id') id: string) | +| @query(paramName?: string) | Injects a parameter from the request URL query string. | execute(@query('searchTerm') searchTerm: string) | +| @body() | Injects the request body payload. | execute(@body() body: MyDTO) | +| @headers(headerName?: string) | Injects a header from the request headers. | execute(@headers('authorization') auth: string) | +| @cookies(cookieName?: string) | Injects a cookie from the request cookies. | execute(@cookies('session') session: string) | +| @next() | Injects the Express NextFunction object. | execute(@next() next: NextFunction) | --- @@ -67,4 +67,4 @@ ExpressoTS is an MIT-licensed open source project. It's an independent project w - 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 \ No newline at end of file +- Share the project with your friends and colleagues diff --git a/docs/overview/dependencies.md b/docs/overview/dependencies.md index 91e7913f..96dc4941 100644 --- a/docs/overview/dependencies.md +++ b/docs/overview/dependencies.md @@ -10,16 +10,15 @@ The purpose of this section is to list all dependencies used by ExpressoTS and o We know that dependencies accelerate the development process, but it also increases the projects complexity and maintenance cost. Another aspect we consider is the potential security risks that a dependency could bring the project. -Our goal is to keep the number of dependencies as low as possible, using only those that are necessary and not part of our core ExpressoTS framework mechanics. With that in mind, the Roadmap includes some dependencies that we hope to replace by our own implementation. More information will come on this. +Our goal is to keep the number of dependencies as low as possible, using only those that are necessary and not part of our core ExpressoTS framework mechanics. With that in mind, the Roadmap includes some dependencies that we hope to replace by our own implementation. More information will come on this. For now, we will keep a vigilant watch on included dependencies, using tools like **[Dependabot](https://dependabot.com/)** to keep them up to date and also using tools like **[Snyk](https://snyk.io/)** to monitor the security risks. -## Utilities +## Utilities (Dev Dependencies) - @commitlint/cli: Lint commit messages - @commitLint/config-conventional: Lint commit messages - @release-it/conventional-changelog: Generate changelog -- chalk: Terminal string styling - dotenv: Loads environment variables from .env file - husky: Git hooks - prettier: Code formatter @@ -31,15 +30,13 @@ For now, we will keep a vigilant watch on included dependencies, using tools lik - express: Http server framework - inversify: IoC container -- inversify-express-utils: Express integration for inversify - inversify-binding-decorators: Decorators for inversify -- winston: Logging library - reflect-metadata: Polyfill for metadata reflection API ## Test -- jest: Testing framework -- ts-jest: Typescript support for jest +- vitest: Testing framework +- vite: Vitest's requirement --- @@ -52,4 +49,4 @@ ExpressoTS is an MIT-licensed open source project. It's an independent project w - 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 \ No newline at end of file +- Share the project with your friends and colleagues diff --git a/docs/overview/first-steps.md b/docs/overview/first-steps.md index 55cfa908..6e00cf37 100644 --- a/docs/overview/first-steps.md +++ b/docs/overview/first-steps.md @@ -4,7 +4,7 @@ sidebar_position: 1 # First Steps -In this section, you will delve into the core concepts of ExpressoTS. To familiarize yourself with the framework and its building blocks, we'll guide you through the process of building a simple non-opinionated project from scratch. This will help you understand some of the initial framework concepts and get started with ExpressoTS. +In this section, you will delve into the core concepts of ExpressoTS to familiarize yourself with the framework and its building blocks. ## The technology @@ -49,6 +49,7 @@ ExpressoTS offers two options for project templates: - Non-opinionated: Want to have the liberty to build and structure your project as you wish? Non opinionated template offers a very small footprint, with only the necessary files to get you started. - Opinionated: Opinionated template is made for more complex projects, as it provides a more layered architecture. + ::: After creating your project, with the desired ``, and depending on the project template you have selected, your project will have a different folder and file structure. Here are the specific folder and file structures for each project template: @@ -72,13 +73,13 @@ project-name/ | `app.container.ts` | The Inversify Server container is responsible for organizing all the modules of the application into a cohesive unit. | | `app.controller.ts` | A basic controller with a single route. | | `app.module.ts` | Application root module. | -| `app.usecase.ts` | A basic use case with a single method, called `execute()`. | +| `app.usecase.ts` | A basic use case with a single method, called `execute()`. | | `main.ts` | The main entry point of an ExpressoTS application. | | `app.usecase.spec.ts` | A basic unit test for the app.usecase. | ### Opinionated project template -In the opininated project template we provide a full CRUD example for a user entity, with all the necessary layers and files to get you started. +In the opinionated project template we provide a full CRUD example for a user entity, with all the necessary layers and files to get you started. ```tree project-name/ @@ -123,41 +124,39 @@ project-name/ │ ├── env.ts │ ├── main.ts ├── test/ -│ ├── ping.usecase.spec.ts +│ ├── app.usecase.spec.ts ``` -| File Name | Description | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------- | -| `entities/` | This folder contains class definitions, or models with their attributes, properties and methods. | -| `providers/` | This folder contains the layer responsible to provide externals resources to the application, also known as adapters. | -| `repositories/` | Additional folder containing an example of repository pattern implementation, database layer communication. | -| `useCases/` | The use case folder contains the use cases implementation of operations that can be performed in the application. | -| `app.container.ts` | The Inversify Server container is responsible for organizing all the modules of the application into a cohesive unit. | -| `env.ts` | This is an utility resource that maps .env variables. | -| `main.ts` | The main entry point of an ExpressoTS application. | -| `ping.usecase.spec.ts` | A basic unit test for the ping.usecase. | +| File Name | Description | +| --------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `entities/` | This folder contains class definitions, or models with their attributes, properties and methods. | +| `providers/` | This folder contains the layer responsible to provide externals resources to the application, also known as adapters. | +| `repositories/` | Additional folder containing an example of repository pattern implementation, database layer communication. | +| `useCases/` | The use case folder contains the use cases implementation of operations that can be performed in the application. | +| `app.container.ts` | The Inversify Server container is responsible for organizing all the modules of the application into a cohesive unit. | +| `env.ts` | This is an utility resource that maps .env variables. | +| `main.ts` | The main entry point of an ExpressoTS application. | +| `app.usecase.spec.ts` | A basic unit test for the app.usecase. | Below you can find some extra information about **[Providers](./providers.md)**, **[Use Cases](./usecase.md)** and the **[Main](./application.md)** entry point of an ExpressoTS application used in the Opinionated template. #### Providers -Contain 3 providers: +Contain 2 providers: - application: This provider is a class that extend from the Application class from @expressots/core that provides the application **[Life Cycle Hooks](application.md#lifecycle-hooks)**. -- bindingType/singleton: This provider lets you bind a class as a singleton. We use this provider to bind the InMemoryDB class as a singleton so that we can use the same instance of the InMemoryDB class throughout the application. - - db-in-memory: This is a simple in-memory database provider that allows you to store data in memory. We use this provider in the User use cases to store and retrieve user data. :::info -bindingType and InMemoryDB provider is an example supplied to help you get started with a simple CRUD operation. You can remove this provider if you wish. +InMemoryDB provider is an example supplied to help you prototype endpoints quickly without having to worry about setting up a database. It is not intended to be used in production. You can replace it with your own database provider. ::: #### Use cases -The use cases in the Opinionated template are organized in 3 modules: +The use cases in the Opinionated template are organized in 2 modules: -- AppModule, PingModule and UserModule, providing some examples of usage of the ExpressoTS resources. For more information about modules, please check the **[Modules Section](./module.md)**. +- AppModule and UserModule, providing some examples of usage of the ExpressoTS resources. For more information about modules, please check the **[Modules Section](./module.md)**. Here are the endpoints in each module: @@ -175,36 +174,9 @@ The `main.ts` includes an async function that will bootstrap the ExpressoTS appl ##### Opinionated in its simple form ```typescript -// Using opinionated start project where App extends @expressots/core Application class -async function bootstrap() { - const app = App.create(container); - app.listen(3000, ServerEnvironment.Production); -} -``` - -##### Opinionated using .env - -```typescript -// Using the opinionated starter project where App extends Application class from @expressots/core -async function bootstrap() { - const app = App.create(container); - app.listen(3000, ServerEnvironment.Production, { - appName: ENV.Application.APP_NAME, - appVersion: ENV.Application.APP_VERSION, - }); -} - -// Or from .env async function bootstrap() { - const app = App.create(container); - app.listen( - ENV.Application.PORT, - ServerEnvironment[ENV.Application.ENVIRONMENT], - { - appName: ENV.Application.APP_NAME, - appVersion: ENV.Application.APP_VERSION, - } - ); + const app = await AppFactory.create(container, App); + await app.listen(3000, ServerEnvironment.Development); } bootstrap(); @@ -213,84 +185,29 @@ bootstrap(); ##### Non opinionated ```typescript -// Using the non-opinionated starter project where AppInstance is an instance of the Application class from @expressots/core async function bootstrap() { - const app = AppInstance.create(container); - app.listen(3000, ServerEnvironment.Development); + const app = await AppFactory.create(container, []); + await app.listen(3000, ServerEnvironment.Development); } bootstrap(); ``` -## Application or AppInstance +## AppExpress or Middleware To bootstrap an ExpressoTS application, there are two ways: -- Using the AppInstance: which is an instance of the Application class that provides the `create()` and `listen()` methods. -- Extending the Application class. By extending the Application class, you can take advantage of its built-in mechanisms for controlling the **[application life cycle hooks](application.md#application-lifecycle-hooks)**, such as injecting and executing services before, after, and during application shutdown. - -Application Instance - -```typescript -import { AppInstance, ServerEnvironment } from "@expressots/core"; -import { container } from "./app-container"; - -export async function bootstrap() { - const app = AppInstance.create(container); - app.listen(3000, ServerEnvironment.Development); -} - -bootstrap(); -``` - -Extending the Application class. Inside of the provider folder, create a folder called `application` and create a new file called `application.provider.ts` and add the following code: - -```typescript -import { Application, Environments, LogLevel, log } from "@expressots/core"; -import { provide } from "inversify-binding-decorators"; - -@provide(App) -class App extends Application { - protected configureServices(): void { - Environments.checkAll(); - } - - // eslint-disable-next-line @typescript-eslint/no-empty-function - protected postServerInitialization(): void {} - - protected serverShutdown(): void { - log(LogLevel.Info, "Server is shutting down", "logger-provider"); - super.serverShutdown(); - } -} - -const appInstance = new App(); - -export { appInstance as App }; -``` - -Application Bootstrap ignited by the extended Application class +- Non-opinionated template using the AppFactory to creates an instance of the default ExpressoTS adapter which is the Express.js. User can directly pass an array of middleware to the `AppFactory.create` method, which will be responsible for creating an Expressjs application with the provided middleware. This method of creating an ExpressoTS application exposes the Expressjs application instance, which can be used to add additional middleware or to configure the Expressjs application. -```typescript -import { App } from "@providers/application/application.provider"; -import { container } from "app-container"; -import { ServerEnvironment } from "@expressots/core"; - -async function bootstrap() { - const app = App.create(container); - app.listen(3000, ServerEnvironment.Development); -} - -bootstrap(); -``` +- Opinionated template using the AppFactory to create an AppExpress application. By using the App (AppExpress) class, you can take advantage of its built-in mechanisms for controlling the **[application life cycle hooks](application.md#application-lifecycle-hooks)**, such as injecting and executing services before, after, and during application shutdown. ## The container -In ExpressoTS, creating an application server to listen to inbound HTTP requests is not enough. The framework requires the creation of a container that organizes all application modules into a cohesive unit. Typically, this container is created in the app-container.ts file. The container is responsible for managing the application's dependencies. Read more about the `app-container` in the **[App Container](app-container.md)** section. +In ExpressoTS, creating an application server to listen to inbound HTTP requests is not enough. The framework requires the creation of a container that organizes all application modules into a cohesive unit. Typically, this container is created in the `app.container.ts` file. The container is responsible for managing the application's dependencies. Read more about the `app.container` in the **[App Container](app-container.md)** section. ### Application uses the container -After the container is created in the `app-container` file, the application can be created by passing the container as a parameter to the `AppInstance.create(container)` method or by extending the Application class. +After the container is created in the `app.container` file, the application can be created by passing the container as a parameter to the `AppFactory.create(container)` method. ### Injecting modules in the container @@ -308,7 +225,7 @@ After creating a module, the module can be added in the container, and after cre #### Application creation ```typescript -const app = AppInstance.create(container); +const app = await AppFactory.create(container); ``` #### Module injection @@ -316,7 +233,7 @@ const app = AppInstance.create(container); ```typescript const appContainer = new AppContainer(); -const container = appContainer.create([ +const container: Container = appContainer.create([ // Add your modules here AppModule, ]); @@ -325,7 +242,7 @@ const container = appContainer.create([ #### Controller injection ```typescript -const appModule = CreateModule([ +const appModule: ContainerModule = CreateModule([ // Add your controllers here AppController, ]); @@ -361,12 +278,38 @@ npm run prod Once the application is up and running, you can access it by navigating to `http://localhost:3000/`. ::: +## Deprecated features + +:::warning Deprecation warning +The following features are valid until version `1.9.0` as they were deprecated in favor of the new `@expressots/core` package version `2.0.0`. +::: + +### Opinionated Application Bootstrap (deprecated) + +```typescript +// Using opinionated start project where App extends @expressots/core Application class +async function bootstrap() { + const app = App.create(container); + app.listen(3000, ServerEnvironment.Production); +} +``` + +### Non opinionated Application Bootstrap (deprecated) + +```typescript +// Using the non-opinionated starter project where AppInstance is an instance of the Application class from @expressots/core +async function bootstrap() { + const app = AppInstance.create(container); + app.listen(3000, ServerEnvironment.Development); +} + +bootstrap(); +``` + ## Note ExpressoTS is a versatile framework that is not bound to any specific platform or technology. Leveraging popular Node.js libraries like InversifyJS and Express.js, it is designed to be lightweight, modular, customizable, and easy to use. Developers can expand the framework's capabilities by creating new providers that can be incorporated into their applications. -We are currently working on building the project RoadMap and plan to add support for other popular Node.js HTTP frameworks, like Fastify and Koa, to the platform. Additionally, as we move towards the future, we intend to eliminate some of the dependencies that are currently part of the framework's core, and replacing them with our own custom implementations to make the framework more secure, reliable and efficient. - --- ## Support the project diff --git a/docs/overview/img/app-life-cycle.png b/docs/overview/img/app-life-cycle.png index 78d1c38d..e12d9c46 100644 Binary files a/docs/overview/img/app-life-cycle.png and b/docs/overview/img/app-life-cycle.png differ diff --git a/docs/overview/img/app-overview.png b/docs/overview/img/app-overview.png index f4b1ec44..48cdec2d 100644 Binary files a/docs/overview/img/app-overview.png and b/docs/overview/img/app-overview.png differ diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/overview/application.md b/i18n/pt/docusaurus-plugin-content-docs/current/overview/application.md index 99378e90..33d36c3c 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/overview/application.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/overview/application.md @@ -4,96 +4,92 @@ sidebar_position: 2 # Aplicação -A Visão Geral da Aplicação fornece uma demonstração abrangente dos principais componentes de uma aplicação ExpressoTS. No coração de uma aplicação ExpressoTS encontra-se a classe Application, que serve como base para criar e configurar o servidor. Além disso, a classe Application faz uso do container de aplicação do Inversify que carrega todos os módulos, incluindo suas respectivas rotas [controllers]. Isso garante um processo simplificado e eficiente para lidar com as solicitações de entrada e fornecer as respostas apropriadas. +A Visão Geral da Aplicação oferece uma demonstração abrangente dos principais componentes de uma aplicação ExpressoTS. No coração de uma aplicação ExpressoTS está a classe Application. Ela serve como base para criar e configurar o servidor. Além disso, a classe Application utiliza o container de aplicação do Inversify para carregar todos os módulos, incluindo suas respectivas rotas [controladores]. Isso garante um processo eficiente para lidar com solicitações recebidas e entregar as respostas apropriadas. -![Application Overiview](./img/app-overview.png) +![Visão Geral da Aplicação](./img/app-overview.png) -ExpressoTS é um framework para aplicações web que fornece uma camada simples de abstração em torno de servidores HTTP populares como **[Express](https://expressjs.com)**, **[Fastify](https://www.fastify.io/)**, ou **[Koa](https://koajs.com/)**. +ExpressoTS é um framework de aplicação web que fornece um invólucro em torno de servidores HTTP populares, incluindo **[Express](https://expressjs.com)** e **[Fastify](https://www.fastify.io/)**. :::info -Atualmente, o ExpressoTS suporta apenas o Express, pois testamos minuciosamente essa integração. +Atualmente, apenas o Express foi completamente testado pela equipe ExpressoTS. O adaptador Fastify está em desenvolvimento. ::: -A arquitetura de uma aplicação ExpressoTS é baseado no **[Inversify's](https://inversify.io/)** Container IoC, que é usado para identificar e injetar dependências nos construtores de classes. Essa abordagem permite que o contêiner IoC carregue todos os módulos necessários, incluindo suas rotas (controladores) respectivas. Ao usar casos de uso e provedores conforme necessário, os roteadores podem lidar com solicitações recebidas. +A arquitetura de uma aplicação ExpressoTS é construída em torno do container IoC **[Inversify](https://inversify.io/)**, que é usado para identificar e injetar dependências nos construtores das classes. Essa abordagem permite que o container IoC carregue todos os módulos necessários, incluindo suas respectivas rotas (controladores). Ao utilizar casos de uso e provedores conforme necessário, os roteadores podem lidar com solicitações recebidas. -Ao aproveitar o poder do Inversify, o ExpressoTS fornece uma arquitetura escalável e modular que ajuda a desacoplar componentes e melhorar a manutenção do código. Isso permite que os desenvolvedores se concentrem em escrever um código limpo e fácil de manter, em vez de se preocupar com a gestão de dependências. +Ao aproveitar o poder do Inversify, o ExpressoTS fornece um sistema personalizado de Injeção de Dependência que é escalável e modular. Isso cria uma arquitetura que ajuda a desacoplar componentes e melhorar a manutenibilidade, permitindo que os desenvolvedores se concentrem em escrever código limpo e sustentável. -## Detalhe dos componentes da aplicação +## Descrição dos Componentes da Aplicação -| Componente | Descrição | -| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DTO IN / OUT | Objeto de transferência de dados que define o formato do payload de entrada e saída da aplicação. | -| Controller | Componente responsável por processar solicitações e respostas com base na URL e no método HTTP. Ele também valida a conformidade dos dados recebidos. | -| Use Case | Componente responsável por implementar a lógica necessária para manipular as solicitações recebidas do controlador. Quando o controlador recebe uma solicitação HTTP e valida os dados recebidos, ele aciona o caso de uso relevante, passando os dados validados para processamento. O caso de uso executa as operações necessárias com base na solicitação e retorna a resposta apropriada ao controlador, que envia a resposta de volta ao cliente. | -| Provider | Componente responsável por fornecer funcionalidades externas à aplicação. | -| Repository | Componente responsável por fornecer acesso ao banco de dados. | +| Componente | Descrição | +| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DTO IN / OUT | Objeto de transferência de dados que define o formato da carga útil de entrada e saída da aplicação. | +| Controlador | Componente responsável pelo processamento de solicitações e respostas com base na URL e no método HTTP. Também valida a conformidade dos dados recebidos. | +| Caso de Uso | Componente responsável por implementar a lógica necessária para lidar com solicitações recebidas do controlador. Quando o controlador recebe uma solicitação HTTP e valida os dados recebidos, ele aciona o caso de uso relevante, passando os dados validados para processamento. O caso de uso executa as operações necessárias com base na solicitação e retorna a resposta apropriada ao controlador, que, em seguida, envia a resposta de volta ao cliente. | +| Provedor | Componente responsável por fornecer funcionalidade externa à aplicação. | +| Repositório | Componente responsável por fornecer camada de comunicação com o banco de dados. Facilitando conexão e operações CRUD. | :::info -Provedores e repositórios são componentes opcionais. Você pode usá-los se precisar fornecer funcionalidade externa ou acesso ao banco de dados. +Provedores e Repositórios são componentes opcionais. Você pode usá-los se precisar fornecer funcionalidade extra à sua aplicação, como integração de banco de dados, sistema de logs, autenticação, email, etc. ::: ## Fluxo de Trabalho -O fluxo de trabalho de uma aplicação ExpressoTS é direto, conforme mostrado no diagrama acima. +O fluxo de trabalho de uma aplicação ExpressoTS é direto, como mostrado no diagrama acima. -1. Após inicializar a aplicação com todos os seus componentes, incluindo o contêiner, módulos e controladores, o servidor começa a ouvir as solicitações recebidas. -2. Quando uma solicitação é recebida, o servidor procura a rota correspondente e executa o controlador associado, que geralmente expõe endpoints. -3. O controlador então chama o caso de uso relevante, que por sua vez chama o provedor apropriado quando necessário. Os provedores são componentes externos que oferecem funcionalidade adicional à aplicação. +1. Após inicializar a aplicação com todos os seus componentes, incluindo o container, módulos e controladores, o servidor começa a escutar por solicitações recebidas. +2. Quando uma solicitação é recebida, o servidor procura pela rota correspondente e executa o controlador associado, que normalmente expõe endpoints. +3. O controlador então chama o caso de uso relevante, que por sua vez chama o provedor apropriado quando necessário. Provedores são componentes externos que oferecem funcionalidade adicional à aplicação. -:::warning Inicialização da aplicação sem controladores -O ExpressoTS irá impedir que você faça isso, pois não há ouvintes para lidar com as solicitações recebidas. Você verá a seguinte mensagem no console: -**_Nenhum controlador foi encontrado! Por favor, certifique-se de registrar pelo menos um controlador._** +:::warning Inicializando a Aplicação sem um controlador +O ExpressoTS impedirá você de inicializar a Aplicação sem um controlador, já que não há ouvintes para lidar com solicitações recebidas. Você verá a seguinte mensagem no console: +**_Nenhum controlador foi encontrado! Certifique-se de ter registrado pelo menos um Controlador._** ::: -## Classe Aplication +## Classe AppExpress -A classe Application oferece uma forma de criar e configurar o servidor, passando **[Express.js middlewares](https://expressjs.com/en/guide/writing-middleware.html)** ou outro middlewares durante a criação do servidor. +A classe AppExpress oferece uma forma de criar e configurar o servidor, passando **[middlewares do Express.js](https://expressjs.com/en/guide/writing-middleware.html)** ou outros middlewares na criação do servidor. -Definição da classe Aplication +Para criar uma instância de aplicação ExpressoTS, usamos a classe `AppFactory`, que é responsável por criar a instância da aplicação e inicializar o container, módulos e controladores. A função `create()` retorna um IApplicationExpress que fornece um conjunto de métodos para configurar o servidor, incluindo o método `listen()`, que inicia o servidor e escuta por solicitações recebidas. + +### Definição da Classe AppExpress ```typescript -class Application { +class AppExpress { /** - * Configure os serviços que devem ser inicializados antes que o servidor seja iniciado. + * Configure serviços que devem ser inicializados antes do início do servidor. */ protected configureServices(): void {} /** - * Configurar serviços que devem ser executados após a inicialização do servidor. + * Configure serviços que devem ser executados após o início do servidor. */ protected postServerInitialization(): void {} /** - * Execute ações ou limpeza após o desligamento do servidor. + * Execute ações ou limpeza após o encerramento do servidor. */ - protected serverShutdown(): void { - process.exit(0); - } + protected serverShutdown(): void {} - public create( + public async create( container: Container, - middlewares: express.RequestHandler[] = [] - ): Application {} + middlewares: Array = [] + ): Promise {} - public listen( + public async listen( port: number, environment: ServerEnvironment, consoleMessage?: IApplicationMessageToConsole - ) {} + ): Promise {} } ``` -:::info -Também fornecemos uma instância da classe Application chamada **AppInstance**, que expõe apenas os métodos create e listen para o desenvolvedor. Isso é benéfico quando você precisa criar rapidamente um servidor sem ter que criar uma nova classe que estenda a classe Application e acessar seus métodos de ciclo de vida. -::: - -### Método create da aplicação +### Método Create -O método Create permite que os desenvolvedores passem o contêiner e os middlewares para o servidor. Para passar middlewares não é necessário usar `app.use()`, basta passar o middleware e sua configuração conforme demonstrado abaixo: +O método `create()` permite aos desenvolvedores passar o container, middlewares e adaptadores de servidor HTTP para o servidor. Para passar um middleware, você não precisa usar `app.use()`, basta passar o middleware e sua configuração como demonstrado abaixo: ```typescript async function Bootstrap() { - App.create(container, [ + await AppFactory.create(container, [ express.json(), express.urlencoded({ extended: true }), cors({ @@ -103,74 +99,112 @@ async function Bootstrap() { } ``` -### Método listen da aplicação +:::info +Adaptadores são usados para criar o servidor. Atualmente, o Express é o único adaptador disponível. O adaptador Fastify está em desenvolvimento. +Ao criar uma instância de aplicação, você pode passar o adaptador como o terceiro parâmetro. Se você não passar o adaptador, o Express é usado por padrão. +::: + +### Método Listen -O método listen inicia o servidor e escuta as solicitações recebidas. No método listen, os desenvolvedores podem definir não apenas o número da porta, mas também o ambiente do servidor, que pode ser de desenvolvimento, preparação ou produção. Assim como os desenvolvedores podem definir o nome e a versão do aplicativo a ser exibido no console quando o servidor for iniciado, conforme exemplo a seguir: +O método `listen()` inicia o servidor e fica à espera de solicitações recebidas. No método listen, os desenvolvedores podem definir o número da porta e o ambiente do servidor, que pode ser desenvolvimento, homologação ou produção. Os desenvolvedores também podem configurar o nome e a versão do aplicativo para serem exibidos no console quando o servidor for iniciado, conforme mostrado no exemplo a seguir: ```typescript // App listen method app.listen(3000, ServerEnvironment.Development, { - appName: "Your App Name", - appVersion: "v1.0.0" -}) + appName: "Your App Name", + appVersion: "v1.0.0", +}); ``` :::tip -O nome e a versão do seu aplicativo podem ser configurados por meio do arquivo .env ou do arquivo package.json. No modelo opinativo, usamos o arquivo package.json para recuperar o nome e a versão do aplicativo. +O nome e a versão do seu aplicativo podem ser configurados por meio do arquivo .env ou do arquivo package.json. No template opinativo, usamos o arquivo package.json para recuperar o nome e a versão do aplicativo. ::: -### Enum Server Environment da aplicação +### Ambiente do Servidor da Aplicação -Por enquanto, essa funcionalidade é um trabalho em progresso. O que ela faz é exibir o ambiente no console quando o servidor é iniciado. A mensagem colorida no console ajuda os desenvolvedores a identificar rapidamente o ambiente em que o servidor está sendo executado. +Este é um enum que define o ambiente do servidor. Atualmente, os ambientes suportados são desenvolvimento e produção. Após a inicialização do servidor, a estrutura subjacente procurará a variável de ambiente NODE_ENV e definirá o ambiente do servidor de acordo. Se a variável de ambiente NODE_ENV não for definida, o ambiente do servidor será configurado como desenvolvimento por padrão. -Aqui está o enum disponível do ambiente do servidor: +Além disso, no provedor da aplicação, o usuário pode realizar lógica condicional com base no ambiente do servidor. + +```typescript +if (this.isDevelopment()) { + // your logic here +} +``` + +Aqui estão os valores do enum disponíveis para ambientes de servidor: ```typescript ServerEnvironment.Development; -ServerEnvironment.Staging; ServerEnvironment.Production; ``` -:::caution AVISO DE SPOILER -O objetivo dessa funcionalidade é permitir que os desenvolvedores carreguem variáveis de ambiente com base no ambiente em que o servidor está sendo executado. Por exemplo, se o servidor estiver rodando em desenvolvimento, carregue o arquivo .env.dev, se o servidor estiver rodando em staging, carregue o arquivo .env.stg, e se o servidor estiver rodando em produção, carregue o .env.prod arquivo. Além disso, estamos planejando carregar variáveis de ambiente de fontes remotas, como AWS Parameter Store, AWS Secrets Manager, Azure Key, Vault, etc. -::: +## Provedor da Classe App -## Hooks de ciclo de vida da aplicação +O provedor da classe App é o coração do template opinativo da aplicação. É responsável por inicializar a aplicação e fornecer funcionalidades a serem configuradas no processo de inicialização do servidor. Você pode fazer uso dos middlewares e provedores integrados para configurar sua aplicação. -Outro aspecto importante da classe Application são os life cycle hooks. Esses hooks permitem que os desenvolvedores executem código antes, depois e no desligamento do servidor. É importante observar que, para aproveitar esses hooks, os desenvolvedores devem criar uma classe App estendendo a classe Application e substituir os métodos conforme necessário. O exemplo a seguir mostra os life cycle hooks disponíveis no momento: +```typescript +class App extends AppExpress { + private middleware: IMiddleware; + private provider: IProvider; + + constructor() { + super(); + this.middleware = container.get(Middleware); + this.provider = container.get(Provider); + } + + protected configureServices(): void { + this.middleware.addBodyParser(); + this.middleware.setErrorHandler(); + } + + protected postServerInitialization(): void { + if (this.isDevelopment()) { + this.provider.envValidator.checkAll(); + } + } + + protected serverShutdown(): void {} +} +``` + +O provedor da classe App oferece um conjunto de middlewares e provedores prontos para uso que podem ser usados para configurar sua aplicação. Explore as interfaces `IMiddleware` e `IProvider` para ver o que está disponível. + +## Hooks do Ciclo de Vida da Classe App + +Outro aspecto importante da classe de Aplicação são os hooks do ciclo de vida. Esses hooks permitem que os desenvolvedores executem código antes, depois e na desligamento do servidor. É importante observar que, para tirar proveito desses hooks, os desenvolvedores devem criar uma classe App que estenda a classe Application e substituir os métodos conforme necessário. O seguinte exemplo mostra os hooks do ciclo de vida disponíveis no momento: ```typescript - /* Execute serviços antes do servidor iniciar */ + /* Add any service that you want to be initialized before the server starts */ protected configureServices(): void { } - /* Execute serviços depois do servidor iniciar */ + /* Add any service that you want to execute after the server starts */ protected postServerInitialization(): void { } - /* Execute serviços ao servidor ser desligado */ - protected serverShutdown(): void { - process.exit(0); - } + /* Add any service that you want to execute after server is shutdown */ + protected serverShutdown(): void { } ``` -### Ordem de execução dos Hooks +### Hooks Execution Order -![Hooks de ciclo de vida da aplicação](./img/app-life-cycle.png) +![Application Lifecycle Hooks](./img/app-life-cycle.png) -## Scripts da aplicação +## Scripts da Aplicação -Por favor, veja abaixo todos os scripts disponíveis que você pode usar para executar, construir e testar sua aplicação. -A coluna de comando mostra NPM como gerenciador de pacotes, mas você pode usar Yarn ou qualquer outro gerenciador de pacotes de sua escolha. +Abaixo estão os scripts usados para executar, construir e testar sua aplicação. +A coluna de comandos mostra o NPM como gerenciador de pacotes, mas você pode usar o gerenciador de pacotes de sua escolha. -| Script | Descrição | Comando | -| ----------- | ---------------------------------------------------- | ---------------------------- | -| build | Constrói o pacote de produção na pasta ./dist. | npm run build | -| dev | Executa em modo de desenvolvimento com observação. | npm run dev | -| prod | Executa em modo de produção com base no pacote built. | npm run prod | -| test | Executa os testes localizados na pasta test. | npm run test | -| test:watch | Executa os testes em modo de observação e interativo. | npm run test:watch | -| test:cov | Gera relatorio de cobertura de testes. | npm run test:cov | -| format | Formatar código usando prettier. | npm run format | -| lint | Lint código usando eslint. | npm run lint | +| Script | Descrição | Comando | +| ---------- | ----------------------------------------------------- | ------------------ | +| build | Constrói o pacote de produção na pasta ./dist. | npm run build | +| dev | Executa em modo de desenvolvimento com observação. | npm run dev | +| prod | Executa em modo de produção com base no pacote built. | npm run prod | +| test | Executa os testes localizados na pasta test. | npm run test | +| test:watch | Executa os testes em modo de observação e interativo. | npm run test:watch | +| test:cov | Gera relatorio de cobertura de testes. | npm run test:cov | +| format | Formatar código usando prettier. | npm run format | +| lint | Lint código usando eslint. | npm run lint | ## Executando a aplicação @@ -181,16 +215,3 @@ npm run dev Dependendo do ambiente em que está executando a aplicação, você verá a seguinte mensagem no console: `expressots-demo version 1.0.0 is running on port 3000 - Environment: development` - ---- - -## Apoie o projeto - -ExpressoTS é um projeto de código aberto licenciado sob o MIT. É um projeto independente com desenvolvimento contínuo possibilitado graças ao seu suporte. Se você deseja ajudar, por favor considere: - -- Se tornar um **[Sponsor no GitHub](https://github.com/sponsors/expressots)** -- Siga a **[organização](https://github.com/expressots)** no GitHub e de um Star ⭐ no projeto -- Subscreva no nosso canal na Twitch: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)** -- Entre no nosso **[Discord](https://discord.com/invite/PyPJfGK)** -- Contribua submetendo **[issues e pull requests](https://github.com/expressots/expressots/issues/new/choose)** -- Compartilhe o projeto com seus amigos e colegas \ No newline at end of file diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/overview/decorators.md b/i18n/pt/docusaurus-plugin-content-docs/current/overview/decorators.md index 385cc654..9bf4b8f9 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/overview/decorators.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/overview/decorators.md @@ -10,51 +10,51 @@ Aqui está uma lista completa de todos os decoradores que estão disponíveis no Decoradores disponíveis para suas classes. -| Decoradores | Descrição | -| ----------- | ------------------------------------------------------------------------------- | -| @provide | Vincula a classe ao container de injeção de dependência. | -| @provideSingleton | Vincula a classe ao contêiner de injeção de dependência como Singleton. | -| @provideTransient | Vincula a classe ao contêiner de injeção de dependência como Transient. | -| @injectable | Marca a classe como disponível para ser injetada. | -| @inject | Marca a classe como disponível para ser injetada no construtor de outra classe. | +| Decoradores | Descrição | +| ----------------- | ------------------------------------------------------------------------------- | +| @provide | Vincula a classe ao container de injeção de dependência. | +| @provideSingleton | Vincula a classe ao contêiner de injeção de dependência como Singleton. | +| @provideTransient | Vincula a classe ao contêiner de injeção de dependência como Transient. | +| @injectable | Marca a classe como disponível para ser injetada. | +| @inject | Marca a classe como disponível para ser injetada no construtor de outra classe. | ## Decoradores do controlador Decoradores disponíveis para seus controladores. -| Decoradores | Descrição | Exemplo de Uso -| ----------- | ------------------------------ | ------------------------------------------------------------ | +| Decoradores | Descrição | Exemplo de Uso | +| ----------- | ------------------------------------------ | ------------------------------------------------------------ | | @controller | Marca a classe como controlador injetável. | @controller("/path", middleware[]) | -| @scope | Vincula um controlador a um escopo. | @scope(BindingScopeEnum.Singleton, ou Request, ou Transient) | +| @scope | Vincula um controlador a um escopo. | @scope(BindingScopeEnum.Singleton, ou Request, ou Transient) | ### Decoradores de métodos HTTP Decoradores disponíveis para seus métodos de controlador. -| Decorador | Descrição | Uso | -| ----------- | ------------------------------------------------------------------ | ---------------------------- | -| @httpGet | Vincula um método de controlador a um verbo HTTP GET. | @httpGet("/path") | -| @httpPost | Vincula um método de controlador a um verbo HTTP POST. | @httpPost("/path") | -| @httpPut | Vincula um método de controlador a um verbo HTTP PUT. | @httpPut("/path") | -| @httpPatch | Vincula um método de controlador a um verbo HTTP PATCH. | @httpPatch("/path") | -| @httpHead | Vincula um método de controlador a um verbo HTTP HEAD. | @httpHead("/path") | -| @httpDelete | Vincula um método de controlador a um verbo HTTP DELETE. | @httpDelete("/path") | -| @httpMethod | Vincula um método de controlador a um verbo HTTP especificado. | @httpMethod("verb", "/path") | +| Decorador | Descrição | Uso | +| --------- | -------------------------------------------------------------- | ------------------------ | +| @Get | Vincula um método de controlador a um verbo HTTP GET. | @Get("/path") | +| @Post | Vincula um método de controlador a um verbo HTTP POST. | @Post("/path") | +| @Put | Vincula um método de controlador a um verbo HTTP PUT. | @Put("/path") | +| @Patch | Vincula um método de controlador a um verbo HTTP PATCH. | @Patch("/path") | +| @Head | Vincula um método de controlador a um verbo HTTP HEAD. | @Head("/path") | +| @Delete | Vincula um método de controlador a um verbo HTTP DELETE. | @Delete("/path") | +| @Method | Vincula um método de controlador a um verbo HTTP especificado. | @Method("verb", "/path") | ### Decoradores de parâmetros Aqui está uma lista de todos os decoradores de parâmetros disponíveis no ExpressoTS, juntamente com sua descrição e uso: -| Decorador | Descrição | Uso -| ------------------------------------ | ------------------------------------------------------ | -------------------------------------------------------- | -| @request() | Injeta objeto Express Request. | execute(@request() req: Request) -| @response() | Injeta objeto Express Response. | execute(@response() res: Response) -| @requestParam(paramName?: string) | Injeta um parâmetro da URL da solicitação. | execute(@requestParam('id') id: string) -| @queryParam(paramName?: string) | Injeta um parâmetro da string de consulta da URL da solicitação. | execute(@queryParam('searchTerm') searchTerm: string) -| @requestBody() | Injeta a carga útil do corpo da solicitação. | execute(@requestBody() body: MyDTO) -| @requestHeaders(headerName?: string) | Injeta um cabeçalho dos cabeçalhos da solicitação. | execute(@requestHeaders('authorization') auth: string) -| @cookies(cookieName?: string) | Injeta um cookie dos cookies da solicitação. | execute(@cookies('session') session: string) -| @next() | Injeta o objeto NextFunction do Express. | execute(@next() next: NextFunction) +| Decorador | Descrição | Uso | +| ----------------------------- | ---------------------------------------------------------------- | ------------------------------------------------ | +| @request() | Injeta objeto Express Request. | execute(@request() req: Request) | +| @response() | Injeta objeto Express Response. | execute(@response() res: Response) | +| @param(paramName?: string) | Injeta um parâmetro da URL da solicitação. | execute(@param('id') id: string) | +| @query(paramName?: string) | Injeta um parâmetro da string de consulta da URL da solicitação. | execute(@query('searchTerm') searchTerm: string) | +| @body() | Injeta a carga útil do corpo da solicitação. | execute(@body() body: MyDTO) | +| @headers(headerName?: string) | Injeta um cabeçalho dos cabeçalhos da solicitação. | execute(@headers('authorization') auth: string) | +| @cookies(cookieName?: string) | Injeta um cookie dos cookies da solicitação. | execute(@cookies('session') session: string) | +| @next() | Injeta o objeto NextFunction do Express. | execute(@next() next: NextFunction) | --- @@ -67,4 +67,4 @@ ExpressoTS é um projeto de código aberto licenciado sob o MIT. É um projeto i - Subscreva no nosso canal na Twitch: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)** - Entre no nosso **[Discord](https://discord.com/invite/PyPJfGK)** - Contribua submetendo **[issues e pull requests](https://github.com/expressots/expressots/issues/new/choose)** -- Compartilhe o projeto com seus amigos e colegas \ No newline at end of file +- Compartilhe o projeto com seus amigos e colegas diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/overview/dependencies.md b/i18n/pt/docusaurus-plugin-content-docs/current/overview/dependencies.md index 09b54015..f60cb978 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/overview/dependencies.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/overview/dependencies.md @@ -14,12 +14,11 @@ Nosso objetivo é manter o número de dependências o mais baixo possível, tent Enquanto isso, vamos continuar monitorando de perto as dependências, utilizando ferramentas como o **[Dependabot](https://dependabot.com/)** para mantê-las atualizadas e também utilizando ferramentas como o **[Snyk](https://snyk.io/)** para ficar de olho nos riscos de segurança. -## Pacotes Utilitários +## Pacotes Utilitários (Dependencias de Desenvolvimento) - @commitlint/cli: Lint mensagens de commit - @commitLint/config-conventional: Lint mensagens de commit - @release-it/conventional-changelog: Gera changelog -- chalk: Estilo para terminal - dotenv: Carregar variáveis de ambiente - husky: Git hooks - prettier: Formatador de códigos @@ -31,15 +30,13 @@ Enquanto isso, vamos continuar monitorando de perto as dependências, utilizando - express: Servidor Http - inversify: IoC container -- inversify-express-utils: Integração do inversify para o Express - inversify-binding-decorators: Decoradores do inversify -- winston: Lib de log - reflect-metadata: Polyfill para metadados e reflexão ## Teste -- jest: Framework de teste -- ts-jest: Suporte para typescript no jest +- vitest: Framework de teste +- vite: Vitest's requerimento --- @@ -52,4 +49,4 @@ ExpressoTS é um projeto de código aberto licenciado sob o MIT. É um projeto i - Subscreva no nosso canal na Twitch: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)** - Entre no nosso **[Discord](https://discord.com/invite/PyPJfGK)** - Contribua submetendo **[issues e pull requests](https://github.com/expressots/expressots/issues/new/choose)** -- Compartilhe o projeto com seus amigos e colegas \ No newline at end of file +- Compartilhe o projeto com seus amigos e colegas diff --git a/i18n/pt/docusaurus-plugin-content-docs/current/overview/first-steps.md b/i18n/pt/docusaurus-plugin-content-docs/current/overview/first-steps.md index 84c7969f..f5d51cfe 100644 --- a/i18n/pt/docusaurus-plugin-content-docs/current/overview/first-steps.md +++ b/i18n/pt/docusaurus-plugin-content-docs/current/overview/first-steps.md @@ -4,21 +4,21 @@ sidebar_position: 1 # Primeiros Passos -Nesta seção, você vai conhecer alguns dos conceitos fundamentais do ExpressoTS. Para se familiarizar com o framework e seus blocos de construção, vamos guiá-lo através do processo de criação de um projeto simples. Isso ajudará você a entender alguns dos conceitos iniciais do framework e começar a trabalhar com o ExpressoTS. +Nesta seção, você vai mergulhar nos conceitos centrais do ExpressoTS para se familiarizar com o framework e seus componentes básicos. -## ExpressoTS, A ideia +## A Tecnologia -Nós acreditamos no poder das linguagens fortemente tipadas, e o **[TypeScript](https://www.typescriptlang.org/)** é essencial quando se trata de estruturar ou construir aplicações em larga escala no **[NodeJS](https://nodejs.org/)**. No exemplo que demonstraremos, utilizaremos principalmente o TypeScript, e aqui estão os motivos pelos quais o TypeScript é benéfico para o seu projeto: +Acreditamos no poder de linguagens fortemente tipadas, e o **[TypeScript](https://www.typescriptlang.org/)** é essencial quando se trata de estruturar ou construir aplicações em larga escala em **[NodeJS](https://nodejs.org/)**. No exemplo a seguir, usaremos principalmente TypeScript, e aqui estão as razões pelas quais usamos TypeScript: -- Melhora na qualidade do código: A tipagem forte ajuda a capturar erros e bugs no momento da compilação, em vez de em tempo de execução, o que ajuda a melhorar a qualidade geral do código. Isso pode levar a menos falhas e problemas com o código em produção. +- Melhoria da qualidade do código: Tipagem forte ajuda a pegar erros e bugs em tempo de compilação, ao invés de em tempo de execução, o que ajuda a melhorar a qualidade geral do código. Isso pode levar a menos falhas e problemas com o código em produção. -- Melhor escalabilidade: A tipagem forte pode ajudar a tornar o código mais escalável, permitindo refatoração e manutenção mais fácil. Isso ocorre porque a tipagem forte garante que as mudanças no código sejam consistentes e previsíveis, tornando mais fácil adicionar novos recursos ou modificar os existentes. +- Melhor escalabilidade: A tipagem forte pode ajudar a tornar o código mais escalável, permitindo refatorações e manutenções mais fáceis. Isso ocorre porque a tipagem forte garante que as alterações no código sejam consistentes e previsíveis, tornando mais fácil adicionar novos recursos ou modificar os existentes. -- Aumento de produtividade: A tipagem forte pode aumentar a produtividade do desenvolvedor, fornecendo uma melhor ferramenta e suporte do editor, como preenchimento automático de código, inferência de tipo e refatoração automática. Isso pode ajudar os desenvolvedores a escreverem código mais rápido e com menos erros. +- Aumento da produtividade: A tipagem forte pode aumentar a produtividade do desenvolvedor, fornecendo melhores ferramentas e suporte do editor, como conclusão de código, inferência de tipo e refatoração automática. Isso pode ajudar os desenvolvedores a escrever código mais rápido e com menos erros. -- Melhora na colaboração: A tipagem forte pode tornar mais fácil para os desenvolvedores colaborarem, fornecendo uma compreensão compartilhada dos tipos e interfaces usados na base de código. Isso pode ajudar a reduzir mal-entendidos e inconsistências e tornar mais fácil para os desenvolvedores trabalharem juntos na mesma base de código. +- Melhoria da colaboração: A tipagem forte pode facilitar a colaboração entre desenvolvedores, fornecendo um entendimento compartilhado dos tipos e interfaces usados no código-fonte. Isso pode ajudar a reduzir mal-entendidos e inconsistências e tornar mais fácil para os desenvolvedores trabalharem juntos no mesmo código-fonte. -- Melhoria na documentação: A tipagem forte pode ajudar a tornar o código mais auto-documentado, fornecendo uma descrição clara e concisa dos tipos e interfaces usados no código. Isso pode ajudar a reduzir a necessidade de extensos comentários e documentação, tornando o código mais fácil de entender e manter. +- Melhor documentação: A tipagem forte pode ajudar a tornar o código auto-documentado, fornecendo uma descrição clara e concisa dos tipos e interfaces usados no código. Isso pode ajudar a reduzir a necessidade de comentários extensos e documentação, tornando o código mais fácil de entender e manter. ## Pre-requisito @@ -49,9 +49,9 @@ ExpressoTS oferece duas opções de modelos de projetos: - Opinativo: O modelo opinativo é feito para projetos mais complexos, já que fornece uma estrutura de projeto mais robusta e uma arquitetura em camadas. - Não-opinativo: Quer ter a liberdade de construir e estruturar seu projeto como desejar? O modelo não-opinativo oferece uma estrutura simples, com apenas os arquivos necessários para começar. -::: + ::: -Depois de criar seu projeto, com o `nome-do-projeto` desejado e dependendo do tipo de projeto selecionado, seu projeto terá uma estrutura de pasta e arquivo diferente. Aqui estão as estruturas específicas de pasta e arquivo para cada tipo de projeto: +Depois de criar seu projeto, com o `` desejado e dependendo do tipo de projeto selecionado, seu projeto terá uma estrutura de pasta e arquivo diferente. Aqui estão as estruturas específicas de pasta e arquivo para cada tipo de projeto: ### Template não-opinativo @@ -67,14 +67,14 @@ nome-do-projeto/ │ ├── app.usecase.spec.ts ``` -| Nome do Arquivo | Descrição -| --------------------- | -------------------------------------------------------------------------------------------------------------------- | -| `app-container.ts` | O container do Inversify Server é responsável por organizar todos os módulos da aplicação em uma unidade coesa. | -| `app.controller.ts` | Um controller básico com uma rota simples. | -| `app.module.ts` | Módulo da aplicação. | -| `app.usecase.ts` | Um caso de uso com único método, chamado `execute()`. | -| `main.ts` | O ponto de partida de uma aplicação ExpressoTS. | -| `app.usecase.spec.ts` | Exemplo de test unitário do app.usecase. | +| Nome do Arquivo | Descrição | +| --------------------- | --------------------------------------------------------------------------------------------------------------- | +| `app-container.ts` | O container do Inversify Server é responsável por organizar todos os módulos da aplicação em uma unidade coesa. | +| `app.controller.ts` | Um controller básico com uma rota simples. | +| `app.module.ts` | Módulo da aplicação. | +| `app.usecase.ts` | Um caso de uso com único método, chamado `execute()`. | +| `main.ts` | O ponto de partida de uma aplicação ExpressoTS. | +| `app.usecase.spec.ts` | Exemplo de test unitário do app.usecase. | ### Template opinativo @@ -121,41 +121,39 @@ nome-do-projeto/ │ ├── env.ts │ ├── main.ts ├── test/ -│ ├── ping.usecase.spec.ts +│ ├── app.usecase.spec.ts ``` -| Nome do Arquivo | Descrição -| --------------------- | ------------------------------------------------------------------------------------------------------------------------- | -| `entities/` | Esta pasta contém as definições de classe, ou modelos com seus atributos, propriedades e métodos. | -| `providers/` | Esta pasta contém a camada responsável por fornecer recursos externos para a aplicação, também conhecida como adaptadores.| -| `repositories/` | Pasta adicional contendo um exemplo de implementação do padrão de repositório, comunicação com a camada do banco de dados.| -| `useCases/` | A pasta de casos de uso contém a implementação dos casos de uso das operações que podem ser realizadas na aplicação. | -| `app.container.ts` | O container do Inversify Server é responsável por organizar todos os módulos da aplicação em uma unidade coesa. | -| `env.ts` | Este é um recurso de utilidade que mapeia as variáveis .env. | -| `main.ts` | O ponto de entrada principal de uma aplicação ExpressoTS. | -| `ping.usecase.spec.ts` | Um teste unitário básico para o ping.usecase. | +| Nome do Arquivo | Descrição | +| --------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| `entities/` | Esta pasta contém as definições de classe, ou modelos com seus atributos, propriedades e métodos. | +| `providers/` | Esta pasta contém a camada responsável por fornecer recursos externos para a aplicação, também conhecida como adaptadores. | +| `repositories/` | Pasta adicional contendo um exemplo de implementação do padrão de repositório, comunicação com a camada do banco de dados. | +| `useCases/` | A pasta de casos de uso contém a implementação dos casos de uso das operações que podem ser realizadas na aplicação. | +| `app.container.ts` | O container do Inversify Server é responsável por organizar todos os módulos da aplicação em uma unidade coesa. | +| `env.ts` | Este é um recurso de utilidade que mapeia as variáveis .env. | +| `main.ts` | O ponto de entrada principal de uma aplicação ExpressoTS. | +| `app.usecase.spec.ts` | Um teste unitário básico para o app.usecase. | Informações adicionais sobre **[Provedores](./providers.md)**, **[Casos de Uso](./usecase.md)** e o exemplo **[Main](./application.md)** fornecidos no projeto modelo Opinionated. #### Provedores -Existe 3 provedores: +Existe 2 provedores: - application: Esse provedor permite estender a classe Application do @expressots/core, que fornece os **[Life Cycle Hooks](application.md#lifecycle-hooks)**. -- bindingType/singleton: Esse provedor permite ligar uma classe como um singleton. Usamos esse provedor para vincular a classe InMemoryDB como um singleton, para que possamos usar a mesma instância da classe InMemoryDB em toda a aplicação. - - db-in-memory: Esse é um provedor de banco de dados simples em memória que permite armazenar dados em memória. Usamos esse provedor nos casos de uso de usuário para armazenar e recuperar dados de usuário. -:::info -bindingType and InMemoryDB Os provedores são exemplos fornecidos para ajudá-lo a começar. Você pode removê-los se desejar. +::info +InMemoryDB provider is an example supplied to help you prototype endpoints quickly without having to worry about setting up a database. It is not intended to be used in production. You can replace it with your own database provider. ::: #### Caso de uso -Os casos de uso no modelo Opinativo são organizados em 3 módulos: +Os casos de uso no modelo Opinativo são organizados em 2 módulos: -- AppModule, PingModule e UserModule, fornecendo alguns exemplos de utilização dos recursos do ExpressoTS. Para obter mais informações sobre os módulos, consulte a **[Seção de Módulos](./module.md)**. +- AppModule e UserModule, fornecendo alguns exemplos de uso dos recursos do ExpressoTS. Para mais informações sobre módulos, consulte a **[Seção de Módulos](./module.md)**. Aqui estão os endpoints em cada módulo: @@ -220,88 +218,38 @@ async function bootstrap() { bootstrap(); ``` -## Application ou AppInstance - -Para inicializar um aplicativo ExpressoTS, existem duas maneiras: - -- Usando o AppInstance: que é uma instância da classe Application que fornece os métodos `create()` e `listen()`. -- Estendendo a classe Application. Ao estender a classe Application, você pode tirar proveito de seus mecanismos integrados para controlar o **[ganchos do ciclo de vida do aplicativo](application.md#application-lifecycle-hooks)**, como injetar e executar serviços antes, depois e durante o desligamento do aplicativo. - -Application Instance - -```typescript -import { AppInstance, ServerEnvironment } from "@expressots/core"; -import { container } from "./app-container"; - -export async function bootstrap() { - const app = AppInstance.create(container); - app.listen(3000, ServerEnvironment.Development); -} - -bootstrap(); -``` - -Estendendo a classe Application. Dentro da pasta do provedor, crie uma pasta chamada `application` e crie um novo arquivo chamado `application.provider.ts` e adicione o seguinte código: - -```typescript -import { Application, Environments, LogLevel, log } from "@expressots/core"; -import { provide } from "inversify-binding-decorators"; - -@provide(App) -class App extends Application { - protected configureServices(): void { - Environments.checkAll(); - } - - // eslint-disable-next-line @typescript-eslint/no-empty-function - protected postServerInitialization(): void {} - - protected serverShutdown(): void { - log(LogLevel.Info, "Server is shutting down", "logger-provider"); - super.serverShutdown(); - } -} - -const appInstance = new App(); +## AppExpress ou Middleware -export { appInstance as App }; -``` +Para inicializar uma aplicação ExpressoTS, existem duas maneiras: -Application Bootstrap iniciado pela classe Application estendida +## Application ou AppInstance -```typescript -import { App } from "@providers/application/application.provider"; -import { container } from "app-container"; -import { ServerEnvironment } from "@expressots/core"; +Para inicializar um aplicativo ExpressoTS, existem duas maneiras: -async function bootstrap() { - const app = App.create(container); - app.listen(3000, ServerEnvironment.Development); -} +- Template Não-opinativo usando o AppFactory para criar uma instância do adaptador padrão do ExpressoTS, que é o Express.js. O usuário pode passar diretamente um array de middleware para o método AppFactory.create, que será responsável por criar uma aplicação Expressjs com o middleware fornecido. Este método de criação de uma aplicação ExpressoTS expõe a instância da aplicação Expressjs, que pode ser usada para adicionar middleware adicional ou para configurar a aplicação Expressjs. -bootstrap(); -``` +- Template Opinativo usando o AppFactory para criar uma aplicação AppExpress. Ao usar a classe App (AppExpress), você pode tirar proveito de seus mecanismos integrados para controlar os ganchos do ciclo de vida da aplicação, como injetar e executar serviços antes, depois e durante o encerramento da aplicação. -## O Container +## O Contêiner -No ExpressoTS, criar um servidor de aplicativos para ouvir as solicitações HTTP de entrada não é suficiente. O framework exige a criação de um contêiner que organize todos os módulos de aplicativos em uma unidade coesa. Normalmente, esse contêiner é criado no arquivo app-container.ts. Leia mais sobre o `app-container` na seção **[App Container](app-container.md)**. +No ExpressoTS, criar um servidor de aplicação para escutar solicitações HTTP de entrada não é suficiente. O framework requer a criação de um contêiner que organiza todos os módulos da aplicação em uma unidade coesa. Normalmente, esse contêiner é criado no arquivo `app.container.ts`. O contêiner é responsável por gerenciar as dependências da aplicação. Leia mais sobre o app.container na seção **[Contêiner da Aplicação](app-container.md)**. -### A aplicação usa o Container +### A Aplicação Utiliza o Contêiner -Após a criação do container no arquivo `app-container`, a aplicação pode ser criada passando o container como parâmetro para o método `AppInstance.create(container)` ou estendendo a classe Application. +Após a criação do contêiner no arquivo `app.container`, a aplicação pode ser criada passando o contêiner como um parâmetro para o método `AppFactory.create(container)`. -### Injetando módulos no Container +### Injetando Módulos no Contêiner -Uma vez criado o container, módulos podem ser injetados na aplicação. Esses módulos são os blocos de construção de uma aplicação ExpressoTS e são responsáveis por organizar a lógica de negócio da aplicação em camadas, incluindo controladores e casos de uso. +Uma vez criado o contêiner, módulos podem ser injetados na aplicação. Esses módulos são os blocos de construção de uma aplicação ExpressoTS e são responsáveis por organizar a lógica de negócio da aplicação em camadas, já que um módulo é um grupo de funcionalidades ou endpoints também chamados de controladores. Leia mais sobre os módulos na seção **[Módulos](module.md)**. -### Injetando controladores nos módulos +### Injetando Controladores nos Módulos -A camada do controlador lida com as solicitações recebidas e retorna as respostas apropriadas; elas são o ponto de entrada do aplicativo para cada terminal. Leia mais sobre os controladores na seção **[Controllers](controller.md)**. Para tornar um controlador funcional, ele deve ser injetado em um módulo. Isso pode ser feito passando o controlador como um parâmetro para o método `CreateModule`. +A camada de controlador lida com solicitações de entrada e retorna respostas apropriadas, eles são o ponto de entrada da aplicação para cada endpoint. Leia mais sobre os controladores na seção **[Controladores](controller.md)**. Para tornar um controlador funcional, ele deve ser injetado em um módulo. Isso pode ser feito passando o controlador como um parâmetro para o método `CreateModule`. -### Fluxo de aplicação totalmente conectado +### Fluxo de Aplicação Totalmente Integrado -Após a criação de um módulo, o módulo pode ser adicionado ao contêiner e, após a criação dos controladores, os controladores podem ser injetados no módulo, resultando em um fluxo de aplicativo totalmente conectado. O trecho de código a seguir demonstra esse processo: +Após criar um módulo, o módulo pode ser adicionado ao contêiner, e após criar controladores, os controladores podem ser injetados no módulo, resultando em um fluxo de aplicação totalmente integrado. O seguinte trecho de código demonstra esse processo: #### Criação da aplicação @@ -326,7 +274,7 @@ const container = appContainer.create([ const appModule = CreateModule([ // Adicione seus controlers aqui AppController, -]) +]); ``` :::info @@ -359,12 +307,38 @@ npm run prod Uma vez que a aplicação está em execução, você pode acessá-la navegando para `http://localhost:3000/` no projeto starter sem opinião. ::: +## Funcionalidades Obsoletas + +:::warning Aviso de Obsolescência +As seguintes funcionalidades são válidas até a versão 1.9.0, pois foram tornadas obsoletas em favor da nova versão do pacote @expressots/core 2.0.0. +::: + +### Opinionated Application Bootstrap (deprecated) + +```typescript +// Using opinionated start project where App extends @expressots/core Application class +async function bootstrap() { + const app = App.create(container); + app.listen(3000, ServerEnvironment.Production); +} +``` + +### Non opinionated Application Bootstrap (deprecated) + +```typescript +// Using the non-opinionated starter project where AppInstance is an instance of the Application class from @expressots/core +async function bootstrap() { + const app = AppInstance.create(container); + app.listen(3000, ServerEnvironment.Development); +} + +bootstrap(); +``` + ## Resumo ExpressoTS é um framework versátil que não está vinculado a nenhuma plataforma ou tecnologia específica. Aproveitando bibliotecas populares do Node.js como InversifyJS e Express.js, ele é projetado para ser leve, modular, personalizável e fácil de usar. Os desenvolvedores podem expandir as capacidades do framework criando novos provedores que podem ser incorporados em suas aplicações. -Atualmente, estamos trabalhando na construção da RoadMap do projeto e planejamos adicionar suporte para outros populares frameworks HTTP do Node.js, como o Fastify e o Koa, à plataforma. Além disso, à medida que avançamos para o futuro, pretendemos eliminar algumas das dependências que atualmente fazem parte do núcleo do framework, como IoC e decoradores. - --- ## Apoie o projeto @@ -376,4 +350,4 @@ ExpressoTS é um projeto de código aberto licenciado sob o MIT. É um projeto i - Subscreva no nosso canal na Twitch: **[Richard Zampieri](https://www.twitch.tv/richardzampieri)** - Entre no nosso **[Discord](https://discord.com/invite/PyPJfGK)** - Contribua submetendo **[issues e pull requests](https://github.com/expressots/expressots/issues/new/choose)** -- Compartilhe o projeto com seus amigos e colegas \ No newline at end of file +- Compartilhe o projeto com seus amigos e colegas