LogoLogo
Studio
4.4
4.4
  • Harper Docs
  • Getting Started
  • Developers
    • Applications
      • Caching
      • Defining Schemas
      • Defining Roles
      • Debugging Applications
      • Define Fastify Routes
      • Web Applications
      • Example Projects
    • Components
      • Managing
      • Reference
      • Built-In Components
    • REST
    • Operations API
      • Quick Start Examples
      • Databases and Tables
      • NoSQL Operations
      • Bulk Operations
      • Users and Roles
      • Clustering
        • Clustering with NATS
      • Custom Functions
      • Components
      • Registration
      • Jobs
      • Logs
      • Utilities
      • Token Authentication
      • SQL Operations
      • Advanced JSON SQL Examples
    • Real-Time
    • Replication/Clustering
      • Sharding
      • Legacy NATS Clustering
        • Requirements and Definitions
        • Creating A Cluster User
        • Naming A Node
        • Enabling Clustering
        • Establishing Routes
        • Subscription Overview
        • Managing Subscriptions
        • Things Worth Knowing
        • Certificate Management
    • Security
      • JWT Authentication
      • Basic Authentication
      • mTLS Authentication
      • Configuration
      • Users & Roles
      • Certificate Management
    • SQL Guide
      • SQL Features Matrix
      • SQL Date Functions
      • SQL Reserved Word
      • SQL Functions
      • SQL JSON Search
      • SQL Geospatial Functions
    • Miscellaneous
      • Google Data Studio
      • SDKs
      • Query Optimization
  • Administration
    • Best Practices and Recommendations
    • Logging
      • Standard Logging
      • Audit Logging
      • Transaction Logging
    • Clone Node
    • Compact
    • Jobs
    • Harper Studio
      • Create an Account
      • Log In & Password Reset
      • Organizations
      • Instances
      • Manage Databases / Browse Data
      • Manage Clustering
      • Manage Instance Users
      • Manage Instance Roles
      • Manage Applications
      • Instance Metrics
      • Instance Configuration
      • Enable Mixed Content
  • Deployments
    • Configuration File
    • Harper CLI
    • Install Harper
      • On Linux
    • Upgrade a Harper Instance
    • Harper Cloud
      • IOPS Impact on Performance
      • Instance Size Hardware Specs
      • Alarms
      • Verizon 5G Wavelength
  • Technical Details
    • Reference
      • Analytics
      • Architecture
      • Content Types
      • Data Types
      • Dynamic Schema
      • GraphQL
      • Harper Headers
      • Harper Limits
      • Globals
      • Resource Class
      • Transactions
      • Storage Algorithm
    • Release Notes
      • Harper Tucker (Version 4)
        • 4.4.24
        • 4.4.23
        • 4.4.22
        • 4.4.21
        • 4.4.20
        • 4.4.19
        • 4.4.18
        • 4.4.17
        • 4.4.16
        • 4.4.15
        • 4.4.14
        • 4.4.13
        • 4.4.12
        • 4.4.11
        • 4.4.10
        • 4.4.9
        • 4.4.8
        • 4.4.7
        • 4.4.6
        • 4.4.5
        • 4.4.4
        • 4.4.3
        • 4.4.2
        • 4.4.1
        • 4.4.0
        • 4.3.38
        • 4.3.37
        • 4.3.36
        • 4.3.35
        • 4.3.34
        • 4.3.33
        • 4.3.32
        • 4.3.31
        • 4.3.30
        • 4.3.29
        • 4.3.28
        • 4.3.27
        • 4.3.26
        • 4.3.25
        • 4.3.24
        • 4.3.23
        • 4.3.22
        • 4.3.21
        • 4.3.20
        • 4.3.19
        • 4.3.18
        • 4.3.17
        • 4.3.16
        • 4.3.15
        • 4.3.14
        • 4.3.13
        • 4.3.12
        • 4.3.11
        • 4.3.10
        • 4.3.9
        • 4.3.8
        • 4.3.7
        • 4.3.6
        • 4.3.5
        • 4.3.4
        • 4.3.3
        • 4.3.2
        • 4.3.1
        • 4.3.0
        • 4.2.8
        • 4.2.7
        • 4.2.6
        • 4.2.5
        • 4.2.4
        • 4.2.3
        • 4.2.2
        • 4.2.1
        • 4.2.0
        • 4.1.2
        • 4.1.1
        • 4.1.0
        • 4.0.7
        • 4.0.6
        • 4.0.5
        • 4.0.4
        • 4.0.3
        • 4.0.2
        • 4.0.1
        • 4.0.0
        • Tucker
      • HarperDB Monkey (Version 3)
        • 3.3.0
        • 3.2.1
        • 3.2.0
        • 3.1.5
        • 3.1.4
        • 3.1.3
        • 3.1.2
        • 3.1.1
        • 3.1.0
        • 3.0.0
      • HarperDB Penny (Version 2)
        • 2.3.1
        • 2.3.0
        • 2.2.3
        • 2.2.2
        • 2.2.0
        • 2.1.1
      • HarperDB Alby (Version 1)
        • 1.3.1
        • 1.3.0
        • 1.2.0
        • 1.1.0
  • More Help
    • Support
    • Slack
    • Contact Us
Powered by GitBook
On this page
  • Component Configuration
  • Custom Component Configuration
  • Default Component Configuration
  • Extensions
  • Resource Extension
  • Protocol Extension
  1. Developers
  2. Components

Reference

PreviousManagingNextBuilt-In Components

Last updated 2 months ago

The technical definition of a Harper component is fairly loose. In the absolute, simplest form, a component is any JavaScript module that is compatible with the . For example, a module with a singular resources.js file is technically a valid component.

Harper provides many features as built-in components, these can be used directly without installing any other dependencies.

Other features are provided by custom components. These can be npm packages such as and (which are maintained by Harper), or something maintained by the community. Custom components follow the same configuration rules and use the same APIs that Harper's built-in components do. The only difference is that they must be apart of the component's dependencies.

Documentation is available for all and Harper components.

Component Configuration

Harper components are configured with a config.yaml file located in the root of the component module directory. This file is how a component configures other components it depends on. Each entry in the file starts with a component name, and then configuration values are indented below it.

name:
  option-1: value
  option-2: value

It is the entry's name that is used for component resolution. It can be one of the , or it must match a package dependency of the component as specified by package.json. The section provides more details and examples.

For some built-in components they can be configured with as little as a top-level boolean; for example, the extension can be enabled with just:

rest: true

Other components (built-in or custom), will generally have more configuration options. Some options are ubiquitous to the Harper platform, such as the files, path, and root options for a , or package for a . Additionally, can be defined for .

Custom Component Configuration

Any custom component must be configured with the package option in order for Harper to load that component. When enabled, the name of package must match a dependency of the component. For example, to use the @harperdb/nextjs extension, it must first be included in package.json:

{
  "dependencies": {
    "@harperdb/nextjs": "^1.0.0"
  }
}

Then, within config.yaml it can be enabled and configured using:

'@harperdb/nextjs':
  package: '@harperdb/nextjs'
  # ...
{
  "dependencies": {
    "harper-nextjs-test-feature": "HarperDB/nextjs#test-feature"
  }
}

And now in config.yaml:

harper-nextjs-test-feature:
  package: '@harperdb/nextjs'
  files: '/*'
  # ...

Default Component Configuration

Harper components do not need to specify a config.yaml. Harper uses the following default configuration to load components.

rest: true
graphql: true
graphqlSchema:
  files: '*.graphql'
roles:
  files: 'roles.yaml'
jsResource:
  files: 'resources.js'
fastifyRoutes:
  files: 'routes/*.js'
  path: '.'
static:
  files: 'web/**'

If a config.yaml is defined, it will not be merged with the default config.

Extensions

There are two key types of Harper Extensions: Resource Extension and Protocol Extensions. The key difference is a Protocol Extensions can return a Resource Extension.

Functionally, what makes an extension a component is the contents of config.yaml. Unlike the Application Template referenced earlier, which specified multiple components within the config.yaml, an extension will specify an extensionModule option.

  • extensionModule - string - required - A path to the extension module source code. The path must resolve from the root of the extension module directory.

If the extension is being written in something other than JavaScript (such as TypeScript), ensure that the path resolves to the built version, (i.e. extensionModule: ./dist/index.js)

Resource Extension

Keep in mind that the CLI command harperdb restart or CLI argument restart=true only restarts the worker threads. If a component is deployed using harperdb deploy, the code within the setupFile() and setupDirectory() methods will not be executed until the system is completely shutdown and turned back on.

Other than their execution behavior, the handleFile() and setupFile() methods, and handleDirectory() and setupDirectory() methods have identical function definitions (arguments and return value behavior).

Resource Extension Configuration

  • files - string - required - Specifies the set of files and directories that should be handled by the component. Can be a glob pattern.

  • path - string - optional - Specifies the URL path to be handled by the component.

  • root - string - optional - Specifies the root directory for mapping file paths to the URLs.

static:
  files: 'web/**'
  root: 'web'
graphqlSchema:
  files: 'src/schema/*.schema'

Resource Extension API

In order for an extension to be classified as a Resource Extension it must implement at least one of the handleFile(), handleDirectory(), setupFile(), or setupDirectory() methods. As a standalone extension, these methods should be named and exported directly. For example:

// ESM
export function handleFile() {}
export function setupDirectory() {}

// or CJS
function handleDirectory() {}
function setupFile() {}

module.exports = { handleDirectory, setupFile }
export function start() {
  return {
    handleFile () {}
  }
}

handleFile(contents, urlPath, path, resources): void | Promise<void>

setupFile(contents, urlPath, path, resources): void | Promise<void>

These methods are for processing individual files. They can be async.

Remember!

setupFile() is executed once on the main thread during the main start sequence.

handleFile() is executed on worker threads and is executed again during restarts.

Parameters:

  • contents - Buffer - The contents of the file

  • urlPath - string - The recommended URL path of the file

  • path - string - The relative path of the file

  • resources - Object - A collection of the currently loaded resources

Returns: void | Promise<void>

handleDirectory(urlPath, path, resources): boolean | void | Promise<boolean | void>

setupDirectory(urlPath, path, resources): boolean | void | Promise<boolean | void>

These methods are for processing directories. They can be async.

If the function returns or resolves a truthy value, then the component loading sequence will end and no other entries within the directory will be processed.

Remember!

setupFile() is executed once on the main thread during the main start sequence.

handleFile() is executed on worker threads and is executed again during restarts.

Parameters:

  • urlPath - string - The recommended URL path of the file

  • path - string - The relative path of the directory

  • resources - Object - A collection of the currently loaded resources

Returns: boolean | void | Promise<boolean | void>

Protocol Extension

Protocol Extension Configuration

'@harperdb/nextjs':
  package: '@harperdb/nextjs'
  files: '/*'
  prebuilt: true
  dev: false

Protocol Extension API

start(options): ResourceExtension | Promise<ResourceExtension>

startOnMainThread(options): ResourceExtension | Promise<ResourceExtension>

Parameters:

  • options - Object - An object representation of the extension's configuration options.

Since npm allows for a , this can be used to create custom references. For example, to depend on a specific GitHub branch, first update the package.json:

Refer to the documentation for more information on these fields.

A Harper Extension is a extensible component that is intended to be used by other components. The built-in components and are both examples of extensions.

For example, the config.yaml specifies extensionModule: ./extension.js.

It is also recommended that all extensions have a package.json that specifies JavaScript package metadata such as name, version, type, etc. Since extensions are just JavaScript packages, they can do anything a JavaScript package can normally do. It can be written in TypeScript, and compiled to JavaScript. It can export an executable (using the property). It can be published to npm. The possibilities are endless!

Furthermore, what defines an extension separately from a component is that it leverages any of the or APIs. The key is in the name, extensions are extensible.

A Resource Extension is for processing a certain type of file or directory. For example, the built-in extension handles executing JavaScript files.

Resource Extensions are comprised of four distinct function exports, , , , and . The handleFile() and handleDirectory() methods are executed on all worker threads, and are executed again during restarts. The setupFile() and setupDirectory() methods are only executed once on the main thread during the initial system start sequence.

Any can be configured with the files, path, and root options. These options control how files and directories are resolved in order to be passed to the extension's handleFile(), setupFile(), handleDirectory(), and setupDirectory() methods.

For example, to configure the component to server all files from web to the root URL path:

Or, to configure the component to load all schemas within the src/schema directory:

When returned by a , these methods should be defined on the object instead:

A Protocol Extension is a more advanced form of a Resource Extension and is mainly used for implementing higher level protocols. For example, the handles building and running a Next.js project. A Protocol Extension is particularly useful for adding custom networking handlers (see the global API documentation for more information).

In addition to the files, path, and root options, and the package option, Protocol Extensions can also specify additional configuration options. Any options added to the extension configuration (in config.yaml), will be passed through to the options object of the start() and startOnMainThread() methods.

For example, the specifies multiple option that can be included in its configuration. For example, a Next.js app using @harperdb/nextjs may specify the following config.yaml:

Many protocol extensions will use the port and securePort options for configuring networking handlers. Many of the global APIs accept port and securePort options, so components replicated this for simpler pass-through.

A Protocol Extension is made up of two distinct methods, and . Similar to a Resource Extension, the start() method is executed on all worker threads, and executed again on restarts. The startOnMainThread() method is only executed once during the initial system start sequence. These methods have identical options object parameter, and can both return a Resource Extension (i.e. an object containing one or more of the methods listed above).

Returns: Object - An object that implements any of the

variety of dependency configurations
built-in components
Harper Next.js Extension
bin
Harper Next.js Extension
Resource Extension
Protocol Extension
handleFile()
handleDirectory()
setupFile()
setupDirectory()
Resource Extension
Protocol Extension
Resource Extension configuration
Custom Component configuration
start()
startOnMainThread()
Resource Extension APIs
@harperdb/nextjs
@harperdb/apollo
built-in
built-in components
default component configuration
Custom Component Configuration
Resource Extension
custom component
custom options
Protocol Extensions
Harper Next.js Extension
custom
server
server
rest
graphqlSchema
jsResource
jsResource
static
graphqlSchema