Best practices for splitting queries and operations

Hello, as I'm getting familiar with Wasp and OpenSaaS, I've hit a doubt I'd like to solve before I add too many functionalities to my project. Following the vertical feature structure in OpenSaaS, is it advised that I create operations.ts and query.ts under each functionality that requires them, or should I keep them in the top-level operations.ts and queries.ts files? To make it visual
src/
|
|-> feature1/
| [...]
|-> queries.ts <--- This?
|
| ...
|-> queries.ts <--- or everything here?
src/
|
|-> feature1/
| [...]
|-> queries.ts <--- This?
|
| ...
|-> queries.ts <--- or everything here?
I would assume that a good idea is to keep the feature-specific queries inside the feature folder and have all reusable ones available in the top-level file. Am I missing something important?
4 Replies
kapa.ai
kapa.ai3mo ago
Hi @piffio. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, your assumption is correct. Wasp encourages a feature-based structure for organizing your project, especially for projects that are not very small. This means that you should create queries.ts and operations.ts under each feature that requires them. This approach helps to keep your code organized and maintainable, especially as your project grows. Here is an example of how you might structure your project:
src

├── feature1
│ ├── actions.ts -- former feature1Actions.ts
│ ├── queries.ts -- former feature1Queries.ts
│ ├── Feature1Component.tsx
│ └── Feature1.css
├── feature2
│ ├── actions.ts -- former feature2Actions.ts
│ ├── queries.ts -- former feature2Queries.ts
│ ├── Feature2Component.tsx
│ └── Feature2.css
├── MainPage.tsx
└── utils.ts
src

├── feature1
│ ├── actions.ts -- former feature1Actions.ts
│ ├── queries.ts -- former feature1Queries.ts
│ ├── Feature1Component.tsx
│ └── Feature1.css
├── feature2
│ ├── actions.ts -- former feature2Actions.ts
│ ├── queries.ts -- former feature2Queries.ts
│ ├── Feature2Component.tsx
│ └── Feature2.css
├── MainPage.tsx
└── utils.ts
In this structure, each feature has its own actions.ts and queries.ts files, which contain the Actions and Queries specific to that feature. This makes it easy to find and update the code related to a specific feature. However, if you have Queries or Actions that are used across multiple features, you might want to keep them in a top-level queries.ts or actions.ts file for reusability. Remember, the key is to organize your project in a way that makes sense to you and your team, and helps you maintain and scale your codebase effectively. For more information, you can refer to the Wasp documentation on migrating from 0.11.X to 0.12.X (https://wasp-lang.dev/docs/migrate-from-0-11-to-0-12#next-steps), which discusses the new freedom to reorganize your project as you see fit. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @piffio, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Sergio Visinoni
Sergio VisinoniOP3mo ago
@kapa.ai what's the recommended naming for RW operations, is it actions.ts or operations.ts?
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- In Wasp, the recommended naming for files containing operations is actions.ts for Actions and queries.ts for Queries. This is based on the convention used in the Wasp documentation and tutorials. For example, when declaring an Action, you would typically import it from a file named actions.ts:
action createTask {
fn: import { createTask } from "@src/actions",
entities: [Task]
}
action createTask {
fn: import { createTask } from "@src/actions",
entities: [Task]
}
And the corresponding implementation would be in the actions.ts file:
export const createTask: CreateTask<Pick<Task, 'description'>, Task> = async (
args,
context
) => {
const newTask = await context.entities.Task.create({
data: {
description: args.description,
isDone: false,
},
})
return newTask
}
export const createTask: CreateTask<Pick<Task, 'description'>, Task> = async (
args,
context
) => {
const newTask = await context.entities.Task.create({
data: {
description: args.description,
isDone: false,
},
})
return newTask
}
Similarly, for Queries, you would use a queries.ts file. However, these are just conventions and you are free to organize your project as you see fit. The important thing is to ensure that the file location matches the import path in the Wasp declaration. For more information, you can refer to the Wasp documentation on Actions (https://wasp-lang.dev/docs/data-model/operations/actions#declaring-actions) and Queries (https://wasp-lang.dev/docs/data-model/operations/queries). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @piffio, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Sergio Visinoni
Sergio VisinoniOP3mo ago
Thanks, solved!
Want results from more Discord servers?
Add your server