We recommend starting with the Bit Symphony platform as a foundation. It provides a robust set of pre-built APIs and functionalities that you can customize to fit your specific needs. This approach can significantly accelerate your development process and reduce boilerplate code.
To customize UI app layout and routing, register your custom component to the Symphony app layout slot:
// acme-platform.browser.runtime import { AppLayout } from '@acme/acme.layouts.app-layout'; export class AcmePlatformBrowser { static dependencies = [SymphonyPlatformAspect]; static async provider([symphonyPlatform]: [SymphonyPlatformBrowser]) { const acmePlatform = new AcmePlatformNode(); symphonyPlatform.registerLayoutComponent(() => { return <AppLayout />; }); return acmePlatform; } }
For building composable UI, start with the AppLayout
component and the registerLayoutEntry
API. This encourages consistency and reusability within your applications. For layout customization within a Symphony platform, refer to the create platform aspect documentation.
Symphony's API gateway supports Express and GraphQL by default. You can override this default gateway by implementing a custom gateway and registering it with the Symphony platform instance. This allows you to tailor the gateway logic to your specific needs:
export class AcmePlatformNode { static dependencies = [SymphonyPlatformAspect]; static async provider([symphonyPlatform]: [SymphonyPlatformNode]) { const acmePlatform = new AcmePlatformNode(); symphonyPlatform.registerGateway( new MyGateway() ); return acmePlatform; } }
When implementing your API gateway, consider the features and structure of the Symphony default gateway as a starting point. It demonstrates how to handle common gateway tasks
This is often useful to expose a slot API for Aspects to plugin new backend servers and route them using an API gateway. The default Platform aspect is using Apollo GraphQL and ExpressJS to allow for other aspect to introduce a GraphQL and RESTful APIs the registerBackendServer
API method:
export class PeopleNode { static dependencies = [SymphonyPlatformAspect]; static async provider([symphonyPlatform]: [SymphonyPlatformNode]) { symphonyPlatform.registerBackendServer([ { routes: [], gql: gqlSchema, }, ]); } }
You can replace the default backend service implementation with your own by implementing the BackendServer interface. Use the Symphony default backend service implementation as an example to create your own.
Alternatively, you can create your own custom platform aspect and implement the platform API including DOM mounting anc backend infrastructure from scratch.
If you are looking for a fully custom stack, or greater level of control over the [platform] than what is available in Symphony's APIs create your own by running the following command:
bit create platform-aspect wayne-platform
To replace the platform aspect and remove Symphony from your stack, add your custom Platform Aspect to the shell app's platform
property.
import { WaynePlatformAspect } from '@wayne/wayne.wayne-platform'; import { PeopleAspect } from '@wayne/people.people'; export const WaynePlatform = HarmonyPlatform.from({ name: 'wayne-platform', // your fully implemented platform platform: WaynePlatformAspect, aspects: [ PeopleAspect ] }); export default WaynePlatform;
Use the Browser runtime to render UI for the web in SSR and CSR:
import { hydrateRoot } from 'react-dom/client'; export class WaynePlatformBrowser { get apiGatewayUrl() { // Backend API endpoint is wired as an env variable. return process.env.API_GATEWAY; } // render the UI in the browser. render() { // CSR rendering logic. } renderSsr() { // SSR rendering logic. } static async provider() { return new WaynePlatformBrowser(); } }
You can create new runtimes for Harmony by implementing a Runtime. Learn more on implementing Harmony runtimes.
Use the NodeJS runtime to run your servers and return the port and URL to be wired to your other runtimes.
export class WaynePlatformNode { run() { console.log('hello my platform!'); // return the server information to be wired to other runtimes. return { appName: 'wayne-server', port: 5001, url: 'http://localhost:5001' }; } static async provider() { return new WaynePlatformNode(); } }
It is recommended to expose a slot API for registering backend services and orchestrating a micro service architecture. See Wayne Platform example to learn how to use a micro service architecture in Harmony.
The default Platform aspect template uses React Router for routing, and allows for other aspects to plugin a route using the registerRoute
method.
Platform Aspects are tested just like every other Aspect. Learn more on testing Aspects.
You can fork Symphony as a jump start to building your own platform. Run the following command to fork your own platform:
bit fork bitdev.symphony/symphony-platform acme-platform