Home > Web Front-end > JS Tutorial > Building Composable Platforms with Harmony

Building Composable Platforms with Harmony

Patricia Arquette
Release: 2024-12-22 22:17:15
Original
697 people have browsed it

In today’s fast-paced digital landscape, the need for adaptive, scalable, and maintainable software systems is greater than ever.

Traditional monolithic architectures often fall short in meeting these demands due to their rigidity and complexity. Enter Harmony, a framework designed to enable composable platforms with high efficiency and flexibility.

In this article, we'll explore how Harmony, powered by Bit, transforms the way we build and maintain modern applications.

What is Harmony?

Harmony is a minimalistic yet powerful dependency-injection framework tailored for creating composable architectures. By enabling developers to stitch together independently developed Bit components, Harmony allows teams to build applications that are not only modular but also adaptable to evolving business needs. Harmony supports full-stack composability, making it ideal for integrating frontend and backend functionalities into cohesive platforms.

Key Features of Harmony

  • Pluggable Aspects: Modular business features, called aspects, can be easily integrated into platforms.

  • Runtime Flexibility: Official support for Node.js and browser environments ensures compatibility across diverse use cases.

Why Composability Matters

Composability empowers organizations to:

  • Adapt Quickly: New features can be added or updated independently without disrupting the existing system.

  • Promote Reusability: Shared components can be leveraged across multiple projects, reducing duplication and increasing consistency.

  • Foster Collaboration: Teams can work on isolated aspects or components without stepping on each other’s toes.

Building a Composable System with Harmony

As mentioned, the building blocks of a Harmony system are Bit components. However, since Bit components are containers for any unit of software, not every Bit component will do.

Harmony uses components with a specific design to allow them to consume and provide "services" to and from other aspects. These can be frontend-only, backend-only, or full-stack features.

An aspect represents a single business capability that can be plugged into a larger system to form a full solution, a new application.

Building Composable Platforms with Harmony

Aspects extend other aspects by registering to their ‘slot’ API. This inversion of control allows teams to compose features or business capabilities with minimal overhead since the aspect is responsible for the integration, not the system that composes it.

For example, the following Harmony app is an online shop for surfer clothing.

The team responsible for that online store decided to add a blog to their site. After searching for a suitable Aspects on the Bit platform, they came across this Blog aspect. Deciding they wanted to use it, they added it to their Hamrony application:

/**
 * @coponentId: learnbit.apparel-waves/apparel-waves
 * @filename: apparel-waves.bit-app.ts
 */ 

// imports...
import { SymphonyPlatformAspect } from '@bitdev/symphony.symphony-platform';
import { ApparelWavesPlatformAspect } from '@learnbit/apparel-waves.apparel-waves-platform';
import { BlogAspect } from '@learnbit/blog-pbc.blog';

export const ApparelWaves = HarmonyPlatform.from({
  name: 'apparel-waves',
  platform: [
   /**
    * ascpects register themsevles to the 'platform' aspect which
    * is the entry point for this application
    */
    SymphonyPlatformAspect,
    {
      name: 'Apparel Waves',
      slogan: 'Making waves in fashion',
      domain: 'apparel-waves.com',
    },
  ],
  /**
    * aspects can run in multiple runtime environments. here, aspects 
    * provide functionalitis to the NodeJS services and to the web frontend apps
   */
  runtimes: [new BrowserRuntime(), new NodeJSRuntime()],

  aspects: [
    /* 'apperal waves' aspect extends the system with its 
     * own unique functionalities. this aspect is maintained by 
     * a team that composes the apsects for their own solution.
     */
    ApparelWavesPlatformAspect,
    /**
     * the blog aspect extends the system with content 
     * management capabilities. it is maintained by the blog PBC team.
     */
    [
      BlogAspect,
      {
       /**
         * the blog aspect also provide a config api for this app to use
         * in this case, since the the blog uses the Contenful platform,
         * the fusion team need to provide it with their own Contentful space ID
         */        
        spaceId: 'contentful-spaceId',
      },
    ],
  ],
});

export default ApparelWaves;
Copy after login

Building Composable Platforms with Harmony

The Blog aspect registers itself to the platform in several ways:

  1. It extends the system’s GraphQL schema with a node for content retrieval. This is done in the NodeJS Runtime.

  2. It extends the system’s routing with the /blog route. This is done in the Browser Runtime.

  3. It extends the header with an additional item a ‘Blog’ link to /blog. This is done in the Browser Runtime.

NodeJS Runtime

/**
 * @coponentId: learnbit.blog-pbc/blog
 * @filename: blog.node.runtime.ts
 */

export class BlogNode {
  constructor(private config: BlogConfig) {}

  async getBlogPosts() {
    const blogData = new BlogData(this.config);
    return blogData.getBlogPosts();
  }

  static dependencies = [SymphonyPlatformAspect];

  static async provider(
    [symphonyPlatform]: [SymphonyPlatformNode],
    config: BlogConfig
  ) {
    const blog = new BlogNode(config);
    const gqlSchema = blogGqlSchema(blog);

    symphonyPlatform.registerBackendServer([
      {
        gql: gqlSchema,
      },
    ]);

    return blog;
  }
}

export default BlogNode;
Copy after login

Browser Runtime

**
 * @coponentId: learnbit.blog-pbc/blog
 * @filename: blog.browser.runtime.ts
 */


export class BlogBrowser {
  constructor(private config: BlogConfig) {}

  static dependencies = [SymphonyPlatformAspect, HeaderAspect];

  static async provider(
    [symphonyPlatform, header]: [SymphonyPlatformBrowser, HeaderBrowser],
    config: BlogConfig
  ) {
    const blog = new BlogBrowser(config);

    symphonyPlatform.registerRoute([
      {
        path: '/blog',
        component: () => {
          return (
            <apolloblogprovider spaceid="{config.spaceId}">
              <bloglobby></bloglobby>
            </apolloblogprovider>
          );
        },
      },
    ]);

    header.registerLink([{ label: 'Blog', href: '/blog' }]);

    return blog;
  }
}

export default BlogBrowser;
Copy after login

The blog aspect in this example uses the Contentful content management system. It offers a coherent “language” for bought services within the company’s aspect ecosystem, ensuring they can communicate effectively and function seamlessly together.

/**
 * @coponentId: learnbit.blog-pbc/blog
 * @filename: blog-data.ts
 */

import { ApolloClient, InMemoryCache, HttpLink, gql } from '@apollo/client';
import type { BlogConfig } from './blog-config.js';

export class BlogData {
  constructor(private readonly config: BlogConfig) {}

  private contentfulClient = new ApolloClient({
    link: new HttpLink({
      uri: `https://graphql.contentful.com/content/v1/spaces/${this.config.spaceId}`,
      headers: {
        Authorization: `Bearer ${process.env.CONTENTFUL_ACCESS_TOKEN}`,
      },
      fetch,
    }),
    cache: new InMemoryCache(),
  });

  getBlogPosts = async () => {
    const { data } = await this.contentfulClient.query({
      query: gql`
        query GetBlogs {
          pageBlogPostCollection {
            items {
              title
              slug
              author {
                name
              }
            }
          }
        }
      `,
    });
    return data.pageBlogPostCollection.items.map((item) => ({
      title: item.title,
      slug: item.slug,
      author: {
        name: item.author ? item.author.name : null,
      },
    }));
  };
}
Copy after login

Next steps

Explore the "Blog" scope (with the blog aspect)

Visit these Bit scopes to explore demo aspects and fork (copy) them to your Bit workspace to get started quickly.

Visit the Blog scope


Building Composable Platforms with Harmony

Explore the "Apparel Waves" scope (with a Harmony platform)

Visit the Apparel Waves scope


Building Composable Platforms with Harmony

Visit Bit's official documentation

Building Composable Platforms with Harmony

Bit. Composable software.

Bit is build system for development of composable software.

Building Composable Platforms with Harmony bit.dev

The above is the detailed content of Building Composable Platforms with Harmony. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template