Skip to content

Commit

Permalink
feat: add code by example section
Browse files Browse the repository at this point in the history
  • Loading branch information
rsaz committed Oct 8, 2023
1 parent 04c391c commit 5147799
Show file tree
Hide file tree
Showing 14 changed files with 3,229 additions and 2,340 deletions.
8 changes: 8 additions & 0 deletions docs/codebyexample/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Code By Example",
"position": 3,
"link": {
"type": "generated-index",
"description": "ExpressoTS Code by Example"
}
}
67 changes: 67 additions & 0 deletions docs/codebyexample/app-container.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
sidebar_position: 1
---

# Application Container

The application container is a dependency injection container. See [Application Container](../overview/app-container.md) for more information.

```typescript
const appContainer = new AppContainer();

export const container: Container = appContainer.create([
// Add your modules here
AppModule,
]);
```

## Creating AppContainer

The `AppContainer` class takes one optional parameter:

- `defaultScope` is the default binding scope. Use `BindingScopeEnum` to set the default scope (Request, Singleton, Transient).
- `skipBaseClassChecks` is a boolean value that indicates if the container should skip the base class checks. This is useful when you are using abstract classes as binding identifiers or you are extending classes from third-party libraries. Set this value to `true` to skip the base class checks.

:::info
The default scope is `BindingScopeEnum.Request` and `skipBaseClassChecks` is `false`.
:::

```typescript
const appContainer = new AppContainer({
defaultScope: BindingScopeEnum.Request,
skipBaseClassChecks: true,
});
```

The `AppContainer` instance returns an instance of `AppContainer` that gives you access to the following methods:

- `create()` creates the application container.
- `Container` is the dependency injection container instance.
- `getBindingDictionary()` returns the binding dictionary map of classes injected in the dependency injection system.
- `getContainerOptions()` returns the container options.

### Method Create

The `create` method takes one mandatory parameter (array of modules);

```typescript
export const container: Container = appContainer.create([
// Add your modules here
AppModule,
UserModule,
ProductModule,
]);
```

---

## 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
98 changes: 98 additions & 0 deletions docs/codebyexample/bootstrap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
sidebar_position: 0
---

# Bootstrap Method

The `bootstrap` method is the entry point of your application. It is responsible for loading the application configuration, registering middlewares, and starting the application.

- `AppFactory.create()` method is responsible for creating the application instance. It takes two parameters:
- `container` is the dependency injection container. See [App Container](../overview/app-container.md) for more information.
- `middlewares` or `App`
- `Return:` `IApplicationExpress` instance that gives you access to two methods:
- `app.listen()` starts the application.
- `app.setEngine()` sets the application render view engine.

:::info
**`middlewares`** is an array of middlewares that will be registered in the application. (Non-opinionated template)

**`App`** is the application class responsible for all application configuration. (Opinionated template)
:::

## Bootstrap with array of middlewares

Use this method if you are using the non-opinionated template. You have the freedom create your own application class and register your middlewares in your own way.

```typescript
async function bootstrap() {
const app = await AppFactory.create(container, [cors(), helmet()]);
await app.listen(3000, ServerEnvironment.Development);
}

bootstrap();
```

:::tip
**`AppFactory.create(container, [])`** returns an instance of `ApplicationExpress` that gives you direct access to the `ExpressApp` instance.
:::

## Bootstrap with the Application Class

Use this method if you are using the opinionated template. Your application class will be responsible for all application configuration.

```typescript
async function bootstrap() {
const app = await AppFactory.create(container, App);
await app.listen(3000, ServerEnvironment.Development);
}

bootstrap();
```

:::tip
**`AppFactory.create(container, App)`** returns an instance of `IApplicationExpress` that gives you access to `listen()` and `setEngine()` methods.
:::

## Method Listen

The `listen` method is responsible for starting the application. It takes two mandatory parameters and one optional parameter:

- `port` is the port number where the application will be listening. (Mandatory)
- `environment` is the environment where the application will be running. It can be `development` or `production`. Use the enum called `ServerEnvironment`. (Mandatory)
- `consoleMessage` is the message object that will be displayed in the console when the application starts. (Optional)

```typescript
await app.listen(3000, ServerEnvironment.Development, {
appName: "Expressots",
appVersion: "1.0.0",
});
```

:::tip
The ServerEnvironment enum defines the NODE_ENV environment variable automatically. It can be `development` or `production`.
:::

## Method Set Engine

The `setEngine` method is responsible for setting the application render view engine. For now ExpressoTS only supports Handlebars.

```typescript
app.setEngine<IHandlebars>({
extName: "hbs",
viewPath: path.join(__dirname, "..", "views"),
engine: engine({ defaultLayout: "layout", extname: "hbs" }),
});
```

---

## 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
112 changes: 112 additions & 0 deletions docs/codebyexample/controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
sidebar_position: 3
---

# Controllers

Controllers are responsible for handling incoming requests and returning responses to the client.

- For information about `BaseController`, see [BaseController](../overview/controller.md#basecontroller-class).
- For information about HTTP and parameters decorators, see [HTTP and Parameter Decorators](../overview/decorators.md).
- Controllers make use of DTOs to validate the request body, query parameters, and route parameters. See [DTOs](../overview/controller#dto-pattern) for more information.

```typescript
@controller("/")
export class UserGetController extends BaseController {
constructor() {
super();
}

@Get("/")
execute() {
return "Getting a user...";
}
}
```

To create a controller, you need to create a class and decorate it with `@controller` decorator. The `@controller` decorator takes two parameters:

- `path` is the path of the controller. (Mandatory)
- `middlewares` is an array of middlewares. (Optional)

```typescript
@controller("/", express.json(), express.urlencoded({ extended: true }))
```

:::info
Defining middlewares in the controller will apply to all routes of the controller.
:::

## Example of a Controller with Multiple Routes

```typescript
@controller("/user")
export class UserController extends BaseController {
constructor() {
super();
}

@Get("/")
get() {
return "Getting a user...";
}

@Post("/create")
create() {
return "Creating a user...";
}
}
```

## Example of Route with Multiple Middlewares

```typescript
@Get("app", express.json(), express.urlencoded({ extended: true }))
```

:::info
Defining middlewares in the route will apply only to the specific route.
:::

:::info
The controller route path will be concatenated with the individual route path.

```typescript
@controller("/user")
@Post("/create")
```

Final route is `/user/create`.
:::

## Injecting Dependencies into Controllers Constructor

You can inject dependencies into controllers constructor as follows:

```typescript
@controller("/")
class AppController extends BaseController {
constructor(private yourProvider: YourProvider) {
super();
}

@Get("/")
get() {
this.yourProvider.doSomething();
return "Hello ExpressoTS!";
}
}
```

---

## 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
44 changes: 44 additions & 0 deletions docs/codebyexample/entities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
sidebar_position: 5
---

# Entities

Entities are the core of your application. They are the representation of your business objects. For more information about entities, see [Entities](../overview/entities.md).

```typescript
@provide(User)
export class User {
id: string;
name: string;
email: string;

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

:::caution
Don't pass primitive types as parameters to the constructor of your entities. The Dependency Injection Container will not be able to resolve them.

```typescript
constructor(name: string) {
this.name = name;
}
```

:::

---

## 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
47 changes: 47 additions & 0 deletions docs/codebyexample/modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
sidebar_position: 2
---

# Modules

Modules are responsible for registering controllers. See [Modules](../overview/module.md) for more information.

## Creating a Module

The `CreateModule` decorator takes two parameters:

- `controllers` is an array of controllers. (Mandatory)
- `scope` is the binding scope. Use `BindingScopeEnum` to set the scope (Request, Singleton, Transient). (Optional)

:::info
The default scope is `BindingScopeEnum.Request` inherited from `AppContainer`.
:::

```typescript
export const UserModule = CreateModule([], BindingScopeEnum.Request);
```

Example of a module with controllers:

```typescript
export const UserModule = CreateModule([
UserCreateController,
UserDeleteController,
UserUpdateController,
UserFindController,
UserFindallController,
]);
```

---

## 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
Loading

0 comments on commit 5147799

Please sign in to comment.