Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions docs/essential/best-practice.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ head:

Elysia is a pattern-agnostic framework, leaving the decision of which coding patterns to use up to you and your team.

However, there are several concerns from trying to adapt an MVC pattern [(Model-View-Controller)](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) with Elysia, and we found it's hard to decouple and handle types.
However, there are several concerns when trying to adapt an MVC pattern [(Model-View-Controller)](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) with Elysia, and we found it hard to decouple and handle types.

This page is a guide on how to follow Elysia structure best practices combined with MVC pattern but can be adapted to any coding pattern you like.
This page is a guide on how to follow Elysia structure best practices combined with the MVC pattern, but it can be adapted to any coding pattern you prefer.

## Folder Structure

Elysia is unopinionated about folder structure, leaving you to **decide** how to organize your code yourself.

However, **if you don't have a specific structure in mind**, we recommend a feature-based folder structure. Where each feature has its own folder containing controllers, services, and models.
However, **if you don't have a specific structure in mind**, we recommend a feature-based folder structure where each feature has its own folder containing controllers, services, and models.

```
| src
Expand All @@ -46,7 +46,7 @@ However, **if you don't have a specific structure in mind**, we recommend a feat
| index.ts
```

This structure allows you to easily find and manage your code, and keep related code together.
This structure allows you to easily find and manage your code and keep related code together.

Here's an example code of how to distribute your code into a feature-based folder structure:

Expand Down Expand Up @@ -144,12 +144,12 @@ Each file has its own responsibility as follows:
- **Service**: Handle business logic, decoupled from Elysia controller if possible.
- **Model**: Define the data structure and validation for the request and response.

Feels free to abstract this structure to your own needs, and use any coding pattern you like.
Feel free to adapt this structure to your needs and use any coding pattern you prefer.

## Method Chaining
Elysia code should always use **method chaining**.

As Elysia type system is complex, every methods in Elysia returns a new type reference.
As Elysia's type system is complex, every method in Elysia returns a new type reference.

**This is important** to ensure type integrity and inference.

Expand Down Expand Up @@ -181,7 +181,7 @@ app.get('/', ({ store: { build } }) => build)
app.listen(3000)
```

We recommend to <u>**always use method chaining**</u> to provide an accurate type inference.
We recommend to <u>**always use method chaining**</u> to provide accurate type inference.

## Controller
> 1 Elysia instance = 1 controller
Expand Down Expand Up @@ -257,15 +257,15 @@ Service is a set of utility/helper functions decoupled as a business logic to us

Any technical logic that can be decoupled from controller may live inside a **Service**.

There're 2 types of service in Elysia:
There are 2 types of service in Elysia:
1. Non-request dependent service
2. Request dependent service

### ✅ Do: Abstract away non-request dependent service

We recommended to abstract a service class/function away from Elysia.
We recommend abstracting a service class/function away from Elysia.

If the service or function doesn't tied to HTTP request or access a `Context`. It's recommended to abstract it as a static class or function.
If the service or function isn't tied to an HTTP request or doesn't access a `Context`, it's recommended to implement it as a static class or function.

Comment on lines +260 to 269
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Hyphenation/plurality for consistency.
Use “request‑dependent” and pluralize “services”.

-There are 2 types of service in Elysia:
-1. Non-request dependent service
-2. Request dependent service
+There are 2 types of services in Elysia:
+1. Non‑request‑dependent services
+2. Request‑dependent services
@@
-We recommend abstracting a service class/function away from Elysia.
+We recommend abstracting a service class/function away from Elysia.
@@
-If the service or function isn't tied to an HTTP request or doesn't access a `Context`, it's recommended to implement it as a static class or function.
+If the service or function isn’t tied to an HTTP request or doesn’t access a `Context`, implement it as a static class or function.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
There are 2 types of service in Elysia:
1. Non-request dependent service
2. Request dependent service
### ✅ Do: Abstract away non-request dependent service
We recommended to abstract a service class/function away from Elysia.
We recommend abstracting a service class/function away from Elysia.
If the service or function doesn't tied to HTTP request or access a `Context`. It's recommended to abstract it as a static class or function.
If the service or function isn't tied to an HTTP request or doesn't access a `Context`, it's recommended to implement it as a static class or function.
There are 2 types of services in Elysia:
1. Non-request-dependent services
2. Request-dependent services
### ✅ Do: Abstract away non-request dependent service
We recommend abstracting a service class/function away from Elysia.
If the service or function isn’t tied to an HTTP request or doesn’t access a `Context`, implement it as a static class or function.
🤖 Prompt for AI Agents
In docs/essential/best-practice.md around lines 260 to 269, the wording should
use consistent hyphenation and plurality: change “request dependent service” and
“service” instances to “request-dependent services” (and “Non-request dependent
service” to “Non-request-dependent services”) throughout this block; update
headings and the explanatory paragraph to use the hyphenated adjective and
plural form so the terminology is consistent across the section.

```typescript
import { Elysia, t } from 'elysia'
Expand All @@ -291,7 +291,7 @@ If your service doesn't need to store a property, you may use `abstract class` a

### ✅ Do: Request dependent service as Elysia instance

**If the service is a request dependent service** or need to process HTTP request. We recommended to abstract it as Elysia instance to ensure type integrity and inference:
**If the service is a request-dependent service** or needs to process HTTP requests, we recommend abstracting it as an Elysia instance to ensure type integrity and inference:

```typescript
import { Elysia } from 'elysia'
Expand All @@ -318,14 +318,14 @@ const UserController = new Elysia()
```

::: tip
Elysia handle [plugin deduplication](/essential/plugin.html#plugin-deduplication) by default so you don't have to worry about performance, as it's going to be Singleton if you specified a **"name"** property.
Elysia handles [plugin deduplication](/essential/plugin.html#plugin-deduplication) by default, so you don't have to worry about performance, as it will be a singleton if you specify a **"name"** property.
:::

### ✅ Do: Decorate only request dependent property

It's recommended to `decorate` only request dependent property, such as `requestIP`, `requestTime`, or `session`.
It's recommended to `decorate` only request-dependent properties, such as `requestIP`, `requestTime`, or `session`.

Overusing decorator may tied your code to Elysia making it harder to test, and reuse.
Overusing decorators may tie your code to Elysia, making it harder to test and reuse.

Comment on lines 324 to 329
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Hyphenation + plurality + scope caution.
Heading and body should use “request‑dependent” and plural “properties”.

-### ✅ Do: Decorate only request dependent property
+### ✅ Do: Decorate only request‑dependent properties
@@
-It's recommended to `decorate` only request-dependent properties, such as `requestIP`, `requestTime`, or `session`.
+Decorate only request‑dependent properties, such as `requestIP`, `requestTime`, or `session`.
@@
-Overusing decorators may tie your code to Elysia, making it harder to test and reuse.
+Overusing decorators can tie your code to Elysia, making it harder to test and reuse.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### ✅ Do: Decorate only request dependent property
It's recommended to `decorate` only request dependent property, such as `requestIP`, `requestTime`, or `session`.
It's recommended to `decorate` only request-dependent properties, such as `requestIP`, `requestTime`, or `session`.
Overusing decorator may tied your code to Elysia making it harder to test, and reuse.
Overusing decorators may tie your code to Elysia, making it harder to test and reuse.
### ✅ Do: Decorate only request-dependent properties
Decorate only request-dependent properties, such as `requestIP`, `requestTime`, or `session`.
Overusing decorators can tie your code to Elysia, making it harder to test and reuse.
🤖 Prompt for AI Agents
In docs/essential/best-practice.md around lines 324 to 329, update the heading
and body copy to use the hyphenated adjective "request-dependent" and the plural
"properties" (e.g., "Decorate only request-dependent properties") and ensure the
body text similarly uses "request-dependent properties" to keep terminology
consistent and accurate about scope; make the minimal text edits to replace
non-hyphenated and singular forms with these corrected terms.

```typescript
import { Elysia } from 'elysia'
Expand Down