How to prevent init functions from running on all services in Encore.ts

3 days ago 4
ARTICLE AD BOX

This is expected behavior due to how Encore.ts bundles JavaScript - all service code is included in a single bundle, even though each container only hosts one service. To run initialization code conditionally, use appMeta() from the encore.dev package to check which service is hosted in the current container.

The appMeta() function returns metadata about the running application, including a list of services hosted in the current container. You can guard your initialization logic with a check:

import { appMeta } from "encore.dev"; const meta = appMeta(); if (meta.hostedServices.includes("serviceA")) { initServiceA(); }

This works because even though the JavaScript bundle contains code for all services, appMeta().hostedServices only lists the service(s) that are actually running in the current container. In most deployment configurations, each container hosts a single service, so this effectively restricts init code to the correct container.

Relevant docs:

Encore.ts Metadata API

Encore.ts Services

KMorris's user avatar

New contributor

KMorris is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Could use lazy initialization (The Singleton Pattern)

Avoid "eager" initialization at the top level of your files. Instead, use a function or a getter that initializes the resource only the first time it is actually needed by an API call.

let _dbConnection: Connection | null = null; async function getDb() { if (!_dbConnection) { _dbConnection = await connectToExternalResource(); } return _dbConnection; } // In your API handler: export const myApi = api({}, async () => { const db = await getDb(); // Only connects when this API is called });

Max's user avatar

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Read Entire Article