#Separating functions from API

4 messages · Page 1 of 1 (latest)

inland summit
#

I have an API that I like to have structured like this - api.admin.games.editor which requires that the various functions under api.admin.games live in the same games.ts file. These functions are getting quite long and the file is getting very large. What is the best practice for splitting up functions so that I can have different files per function without changing how they're accessed via the API?

supple rootBOT
#

Hi @inland summit. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

The best practice in Convex for managing large files while keeping your API structure (e.g., api.admin.games.editor) is to separate your business logic into helper functions in other files, and keep your API-facing file (e.g., games.ts) as a thin wrapper that simply calls these helpers. This way, you can split up your code for maintainability without changing the API path or how functions are accessed from the client.

How to do it:

  1. Move logic to helpers:
    Create a directory like convex/model/games.ts (or similar) and move the implementation details of each function there as plain TypeScript functions.

  2. Keep API wrappers thin:
    In your games.ts file (which defines api.admin.games.editor, etc.), keep only the function definitions that call into your helpers.

Example:

// convex/model/games.ts
export async function editorLogic(ctx, args) {
  // ...complex logic here
}

// convex/admin/games.ts
import { editorLogic } from "../model/games";
export const editor = mutation({
  args: { /* ... */ },
  handler: editorLogic,
});

This approach is recommended in the Convex documentation:

Most logic should be written as plain TypeScript functions, with the query, mutation, and action wrapper functions being a thin wrapper around one or more helper function. Concretely, most of your code should live in a directory like convex/model, and your public API, which is defined with query, mutation, and action, should have very short functions that mostly just call into convex/model Use helper functions to write shared code.

This lets you keep your API structure unchanged (so api.admin.games.editor still works), while making your codebase more maintainable as it grows.

#

Note:
Convex does not currently support splitting a single API namespace (like api.admin.games) across multiple files while keeping the same API path. The file and export structure directly determines the API path, so all exports for a given namespace must be in the same file. The recommended workaround is to use helpers as described above.

If you want to see more examples, check out the Convex best practices and Splitting up query/mutation code via helpers sections.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: