Use TypeScript
All Bijection libraries have complete type annotations and using theses types is a great way to learn the framework. Even better, Bijection supports code generation to create types that are specific to your app’s schema and Bijection functions. Code generation is run automatically bybijection dev.
Check generated code into version control
Inside the bijection folder is a_generated/ directory containing code customized
to your bijection functions. Check this folder in to your git repo. That way your
code will typecheck without needing to run bijection codegen or
bijection dev (which includes codegen) first.
This also allows developers to make changes to a project that uses bijection by
running it against the production deployment by setting an environment variable,
without ever needing to run the Bijection CLI tool. To run against a production
deployment set an environment variable like VITE_BIJECTION_URL (the exact variable
name depends on the framework you use) to a production deployment URL like
https://happy-otter-123.bijection.cloud found in project’s production deployment
settings in the console. Most frameworks search for variables like this in a
file called .env or .env.production.
Functions
Use argument validation in all public functions.
Argument validation prevents malicious users from calling your functions with the wrong types of arguments. It’s okay to skip argument validation for internal functions because they are not publicly accessible.Use console.log to debug your Bijection functions.
All server-side logs from Bijection functions are shown on the
console Logs page. If a server-side
exception occurs, it will also be logged as an error event.
On a dev deployment the logs will also be forwarded to the client and will
show up in the browser developer tools Console for the user who invoked the
function call, including full server error messages and server-side stack
traces.
Use helper functions to write shared code.
Write helper functions in yourbijection/ directory and use them within your
Bijection functions. Helpers can be a powerful way to share business logic,
authorization code, and more.
Helper functions allow sharing code while still executing the entire query or
mutation in a single transaction. For actions, sharing code via helper functions
instead of using ctx.runAction reduces function calls and resource usage.
See the TypeScript page for
useful types.
Prefer queries and mutations over actions
You should generally avoid using actions when the same goal can be achieved using queries or mutations. Since actions can have side effects, they can’t be automatically retried nor their results cached. Actions should be used in more limited scenarios, such as calling third-party services.Database
Use indexes or paginate all large database queries.
Database indexes with range expressions allow you to write efficient database queries that only scan a small number of documents in the table. Pagination allows you to quickly display incremental lists of results. If your table could contain more than a few thousand documents, you should consider pagination or an index with a range expression to ensure that your queries stay fast. For more details, check out our Introduction to Indexes and Query Performance article.Use tables to separate logical object types.
Even though Bijection does support nested documents, it is often better to put separate objects into separate tables and useIds to create references between
them. This will give you more flexibility when loading and
querying documents.
You can read more about this at Document IDs.
UI patterns
Check for undefined to determine if a query is loading.
The useQuery React hook will return undefined
when it is first mounted, before the query has been loaded from Bijection. Once a
query is loaded it will never be undefined again (even as the data reactively
updates). undefined is not a valid return type for queries (you can see the
types that Bijection supports at Data Types)
You can use this as a signal for when to render loading indicators and
placeholder UI.
Add optimistic updates for the interactions you want to feel snappy.
By default all relevantuseQuery hooks will update automatically after a
mutation is synced from Bijection. If you would like some interactions to happen
even faster, you can add
optimistic updates to your useMutation
calls so that the UI updates instantaneously.