Getting Started
Installation
- Linux
- MacOS
- Windows
Linux - Install from Terminal to /usr/local/bin
:
wget -q https://nanobus.io/install.sh -O - | /bin/bash
MacOS - Install from Terminal to /usr/local/bin
:
curl -fsSL https://nanobus.io/install.sh | /bin/bash
Windows - Install from Command Prompt:
powershell -Command "iwr -useb https://nanobus.io/install.ps1 | iex"
Updates to PATH might not be visible until you restart your terminal application.
Alternatively, you can also install manually from releases or build from source from this GitHub repo.
Getting Started
Prerequisites
Hello World!
Use the apex
CLI to start a new project from the starter template:
apex install https://deno.land/x/nanobus_templates/mod.ts
apex list templates
┌──────────────────────┬──────────────────────┬─────────────────────────────────────────────┐
│ Name │ Version │ Description │
└──────────────────────┴──────────────────────┴─────────────────────────────────────────────┘
@nanobus/init v0.0.23 NanoBus barebones Iota
@nanobus/init-ts v0.0.23 NanoBus barebones Iota with TypeScript
@nanobus/tinygo v0.0.23 NanoBus TinyGo Iota
apex new @nanobus/init my-app
The starter template includes up a nanobus configuration with one sample interface and an action that takes an input named name
.
id: "my-app"
version: 0.0.1
interfaces:
Greeter:
sayHello:
steps:
- name: Say Hello!
uses: expr
with:
value: '"Hello, " + input.name'
Run our action with the nanobus invoke
command with sample input piped from echo
:
echo '{"name": "World!"}' | nanobus invoke bus.yaml Greeter::sayHello
"Hello, World!"
Making a web service
To expose our interface to something other than the command line, we use a transport
. Transports are ways of attaching interfaces to event-based resources, like a web servers, message queues, or schedulers. There are several transports baked into nanobus.
To spin up an HTTP server, use the transport nanobus.transport.http.server/v1
. Use the configuration below to configure it to use port 8080
and use the internal router nanobus.transport.http.router/v1
transports:
http:
uses: nanobus.transport.http.server/v1
with:
address: ":8080"
routers:
- uses: nanobus.transport.http.router/v1
with:
routes:
- method: POST
uri: /hello
handler: Greeter::sayHello
Each route is configured with its method, uri, handler and optional encoding. By default, the encoding is set to the content-type or application/json
but you can specify other formats with the encoding
property.
Our full configuration now looks like this:
id: "my-app"
version: 0.0.1
transports:
http:
uses: nanobus.transport.http.server/v1
with:
address: ":8080"
routers:
- uses: nanobus.transport.http.router/v1
with:
routes:
- method: POST
uri: /hello
handler: Greeter::sayHello
interfaces:
Greeter:
sayHello:
steps:
- name: Say Hello!
uses: expr
with:
value: '"Hello, " + input.name'
Start our web service by running nanobus
and watch nanobus initialize our HTTP server and routes automatically.
nanobus run --debug --developer-mode
INFO Running in Developer Mode!
INFO Initializing codec {"name": "text/plain", "type": "text/plain"}
INFO Initializing codec {"name": "text/html", "type": "text/html"}
INFO Initializing codec {"name": "json", "type": "json"}
INFO Initializing codec {"name": "msgpack", "type": "msgpack"}
INFO Initializing codec {"name": "cloudevents+avro", "type": "cloudevents+avro"}
INFO Initializing codec {"name": "cloudevents+json", "type": "cloudevents+json"}
INFO Initializing transport {"name": "http"}
INFO Serving route {"uri": "/hello", "methods": "POST", "handler": "Greeter::sayHello"}
INFO HTTP server listening {"address": ":8080"}
Make a request with a tool like curl to see the output:
curl 127.0.0.1:8080/hello \
-H "Content-Type: application/json" \
-d '{"name": "World!"}'
{
"type": "permission_denied",
"code": "permission_denied",
"status": 403,
"path": "/hello",
"timestamp": "2023-02-01T15:21:50.067821Z"
}
Permission denied!
An important part of nanobus is making it difficult to cut corners that can lead to catastrophes later. It's too easy to build APIs that ignore authentication and authorization. Adding it as a layer on top of an existing application leads to security holes and major vulnerabilities. Every action in nanobus is deny-by-default. You must explicitly configure what is public and – if it's private – what permissions and roles can access what actions. We haven't run into this error yet because nanobus invoke
on the command line bypasses configured auth requirements.
Add an authorization
block to our configuration and set up our action as unauthenticated.
authorization:
Greeter:
sayHello:
unauthenticated: true
Our full web service configuration now looks like this:
id: "my-app"
version: 0.0.1
transports:
http:
uses: nanobus.transport.http.server/v1
with:
address: ":8080"
routers:
- uses: nanobus.transport.http.router/v1
with:
routes:
- method: POST
uri: /hello
handler: Greeter::sayHello
authorization:
Greeter:
sayHello:
unauthenticated: true
interfaces:
Greeter:
sayHello:
steps:
- name: Say Hello!
uses: expr
with:
value: '"Hello, " + input.name'
Run it with the command nanobus
and issue a curl command to see our output.
curl 127.0.0.1:8080/hello \
-H "Content-Type: application/json" \
-d '{"name": "World!"}'
"Hello, World!"
Congrats! You just put together a web service with nothing more than yaml. We've barely scratched the surface. Extending nanobus with more serious logic is where the power really takes off.