Skip to content

[WIP] Sidecar for Moleculer framework with HTTP support.

License

Notifications You must be signed in to change notification settings

moleculerjs/sidecar

Repository files navigation

Moleculer logo

Integration Test

[WIP] Moleculer Sidecar

Moleculer Sidecar allows using external services (written in other programming languages which is not supported officially) in a Moleculer microservices project. The Sidecar is a HTTP server which gives a REST interface to communicate other Moleculer services instead of implementing the full Moleculer protocol Ă©s Service Registry & Discovery features. Sidecar is a full-fledged MoleculerJS node with all features (e.g. parameter validation, retries, fallback, timeout...etc), it means in the external services, you don't need to implement them because Sidecar manages them.

Features

  • write services any programming languages (which have http server & client support).
  • bundled to executable, no need to install Node.js environment for running.
  • configure Sidecar via environment variables or moleculer.config.js file.
  • contains all official transporter, cacher, discoverer, serializer libraries.
  • easy to add to any Docker image.
  • official Docker image, use it as a Sidecar pod container in Kubernetes cluster.

Install

Using executables

Download binaries from releases.

Docker

Simple start

docker run -p 5103:5103 moleculer/sidecar

Start with REPL mode

docker run --it -p 5103:5103 moleculer/sidecar --repl

Start with config file

docker run -v /my-folder/moleculer.config.js:/sidecar/moleculer.config.js moleculer/sidecar --config

Kubernetes

TODO

Using from source

TODO

Usage (via HTTP interface)

The ServiceBroker inside the Sidecar can be configured via moleculer.config.js file or environment variables. The Sidecar HTTP server is listening on port 5103 (by default). (Why 5103? To make it easier to remember: SIDE = S->5 I->1 D->0 E->3 = 5103). If you don't like it, you can change it with SIDECAR_PORT environment variable.

Register an external service

The request body should contains one or more service schema where the action/event handlers should be an URL what points to the external service HTTP endpoint. In the Service schema you can use all MoleculerJS features (e.g. parameter validation, metrics, tracing, bulkhead, timeout, retries ...etc), they are handled by the Sidecar.

POST /v1/registry/services

Request body

{
    name: "posts",
    version: 1,

    settings: {
        // It means, your HTTP server running on port 5000 and sidecar can reach it on `localhost`
        // The URLs in action/event handlers contains relative URL.
        baseUrl: "http://localhost:5000"
    },

    actions: {
        list: {
            params: {
                limit: "number",
                offset: "number"
            },
            // Shorthand handler URL what will be called by sidecar
            handler: "/actions/posts/list"
        }
    },

    events: {
        "user.created": {
            // Shorthand handler URL what will be called by sidecar
            handler: "/events/user.created"
        }
    }
}

Call a service

Calling comments.create service action.

POST /v1/call/comments.create

Request body

{
    // Context params
    params: {
        title: "Lorem ipsum",
        content: "Lorem ipsum dolor sit amet..."
    },
    // Context meta
    meta: {
        user: {
            id: 12345
        }
    },
    // Calling options
    options: {
        timeout: 3000
    }
}

Response body

{
    // Response data
    response: {
        id: 1,
        title: "Lorem ipsum",
        content: "Lorem ipsum dolor sit amet..."
    },
    // Optional: Context meta if you changed the content.
    meta: {
        user: {
            id: 12345
        }
    }
}

Error response body

{
    error: {
        name: "MoleculerClientError",
        code: 422,
        type: "VALIDATION_ERROR",
        message: "Title is required",
        data: {
            action: "comments.create",
            params: {
                title: null
            }
        }
    }
}

Emit an event

Emit a post.created event.

POST /v1/emit/post.created

In case of broadcast use the following URL:

POST /broadcast/post.created

Request body

{
    // Context params
    params: {
        id: 1,
        title: "First post",
        content: "Post content",
        author: 12345
    },
    // Context meta
    meta: {
        user: {
            id: 12345
        }
    },
    // Emit options
    options: {
        groups: "users"
    }
}

Accepting action requests

If your external service implements actions, you should start a HTTP server. Create an endpoint for the action handler and set the address in the service schema. If another services calls your action, the Sidecar sends a POST request to the defined endpoint with the following request body:

Request body

{
    // Action name
    action: "posts.list",

    // Caller NodeID
    nodeID: "node-123",

    // Context params
    params: {
        limit: 10,
        offset: 50
    },

    // Context meta
    meta: {
        user: {
            id: 12345
        }
    },

    // Calling options
    options: {
        timeout: 3000
    }
}

You should send a response with the following form:

Response body

{
    // Response data
    response: [
        { id: 1, title: "First post" },
        { id: 2, title: "Second post" },
        { id: 3, title: "Third post" }
    ],
    // Optional: Context meta if you changed the content.
    meta: {
        user: {
            id: 12345
        }
    }
}

If an error occured during execution, use correct response status code (4xx, 5xx) and send the following as a response body:

Error response body

{
    // Error data
    error: {
        name: "MoleculerClientError",
        code: 400,
        type: "INVALID_INPUT",
        message: "Some user input is not valid",
        data: {
            // Any useful data
            action: "posts.list",
            params: {
                limit: "asd"
            }
        }
    }
}

Accepting events

If you want to subscribe to Moleculer events, you should start a HTTP server. Create an endpoint for the event handler and set the address in the service schema. If the event emitted, the Sidecar sends a POST request to the defined endpoint with the following request body:

Request body

{
    // Event name
    event: "user.created",

    // Type of event (emit, broadcast)
    eventType: "emit",

    eventGroups: "posts",

    // Caller NodeID
    nodeID: "node-123",

    // Context params
    params: {
        limit: 10,
        offset: 50
    },

    // Context meta
    meta: {
        user: {
            id: 12345
        }
    }
}

Access the Sidecar's broker registry

List of all Moleculer nodes

GET /v1/registry/nodes

List of all Moleculer services

GET /v1/registry/services

List of all Moleculer actions

GET /v1/registry/actions

List of all Moleculer event subscriptions

GET /v1/registry/events

Unregister an external service

You can unregister your service if you call the following endpoint:

DELETE /v1/registry/services/:service-full-name

Example

DELETE /v1/registry/services/v1.posts

Example external services

Go

Using Fiber: examples/full/go-fiber/server.go

Python

Using Flask: examples/full/python-flask/server.py

Ruby

Using Sinatra: examples/full/ruby-sinatra/server.rb

Rust

Using Actix: examples/full/rust-actix/src/main.rs

PHP

Using Mark: examples/full/php-mark/server.php

Ballerina

Using built-in tools examples/full/ballerina/src/server/main.bal

Deno

Using Oak: examples/full/deno-oak/server.ts

Swift

Using Perfect: examples/full/swift-perfect/Sources/server/main.swift

Crystal

Using kemal: examples/full/crystal-kemal/server.cr

C#

TODO

C++

TODO

Kotlin

TODO

Delphi

TODO

Contribution

Please send pull requests improving the usage and fixing bugs, improving documentation and providing better examples, or providing some testing, because these things are important.

License

The project is available under the MIT license.

Contact

Copyright (c) 2021 MoleculerJS

@MoleculerJS @MoleculerJS