Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
- Loading branch information
Showing
1 changed file
with
189 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
# NATS micro | ||
|
||
- [Overview](#overview) | ||
- [Basic usage](#basic-usage) | ||
- [Endpoints and groups](#endpoints-and-groups) | ||
- [Discovery and Monitoring](#discovery-and-monitoring) | ||
- [Examples](#examples) | ||
- [Documentation](#documentation) | ||
|
||
## Overview | ||
|
||
The `micro` package in the NATS.go library provides a simple way to create | ||
microservices that leverage NATS for scalability, load management and | ||
observability. | ||
|
||
## Basic usage | ||
|
||
To start using the `micro` package, import it in your application: | ||
|
||
```go | ||
import "github.com/nats-io/nats.go/micro" | ||
``` | ||
|
||
The core of the `micro` package is the Service. A Service aggregates endpoints | ||
for handling application logic. Services are named and versioned. You create a | ||
Service using the `micro.NewService()` function, passing in the NATS connection | ||
and Service configuration. | ||
|
||
```go | ||
nc, _ := nats.Connect(nats.DefaultURL) | ||
|
||
// request handler | ||
echoHandler := func(req micro.Request) { | ||
req.Respond(req.Data()) | ||
} | ||
|
||
srv, err := micro.AddService(nc, micro.Config{ | ||
Name: "EchoService", | ||
Version: "1.0.0", | ||
// base handler | ||
Endpoint: µ.EndpointConfig{ | ||
Subject: "svc.echo", | ||
Handler: micro.HandlerFunc(echoHandler), | ||
}, | ||
}) | ||
``` | ||
|
||
After creating the service, it can be accessed by publishing a request on | ||
endpoint subject. For given configuration, run: | ||
|
||
```sh | ||
nats req svc.echo "hello!" | ||
``` | ||
|
||
To get: | ||
|
||
```sh | ||
17:37:32 Sending request on "svc.echo" | ||
17:37:32 Received with rtt 365.875µs | ||
hello! | ||
``` | ||
|
||
## Endpoints and groups | ||
|
||
Base endpoint can be optionally configured on a service, but it is also possible | ||
to add more endpoints after the service is created. | ||
|
||
```go | ||
srv, _ := micro.AddService(nc, config) | ||
|
||
// endpoint will be registered under "svc.add" subject | ||
err = srv.AddEndpoint("svc.add", micro.HandlerFunc(add)) | ||
``` | ||
|
||
In the above example `svc.add` is an endpoint name and subject. It is possible | ||
have a different endpoint name then the endpoint subject by using | ||
`micro.WithEndpointSubject()` option in `AddEndpoint()`. | ||
|
||
```go | ||
// endpoint will be registered under "svc.add" subject | ||
err = srv.AddEndpoint("Adder", micro.HandlerFunc(echoHandler), micro.WithEndpointSubject("svc.add")) | ||
``` | ||
|
||
Endpoints can also be aggregated using groups. A group represents a common | ||
subject prefix used by all endpoints associated with it. | ||
|
||
```go | ||
srv, _ := micro.AddService(nc, config) | ||
|
||
numbersGroup := srv.AddGroup("numbers") | ||
|
||
// endpoint will be registered under "numbers.add" subject | ||
_ = numbersGroup.AddEndpoint("add", micro.HandlerFunc(addHandler)) | ||
// endpoint will be registered under "numbers.multiply" subject | ||
_ = numbersGroup.AddEndpoint("multiply", micro.HandlerFunc(multiplyHandler)) | ||
``` | ||
|
||
## Discovery and Monitoring | ||
|
||
Each service is assigned a unique ID on creation. A service instance is | ||
identified by service name and ID. Multiple services with the same name, but | ||
different IDs can be created. | ||
|
||
Each service exposes 3 endpoints when created: | ||
|
||
- PING - used for service discovery and RTT calculation | ||
- INFO - returns service configuration details (used subjects, service metadata | ||
etc.) | ||
- STATS - service statistics | ||
|
||
Each of those operations can be performed on 3 subjects: | ||
|
||
- all services: `$SRV.<operation>` - returns a response for each created service | ||
and service instance | ||
- by service name: `$SRV.<operation>.<service_name>` - returns a response for | ||
each service with given `service_name` | ||
- by service name and ID: `$SRV.<operation>.<service_name>.<service_id>` - | ||
returns a response for a service with given `service_name` and `service_id` | ||
|
||
For given configuration | ||
|
||
```go | ||
nc, _ := nats.Connect("nats://localhost:4222") | ||
echoHandler := func(req micro.Request) { | ||
req.Respond(req.Data()) | ||
} | ||
|
||
config := micro.Config{ | ||
Name: "EchoService", | ||
Version: "1.0.0", | ||
Endpoint: µ.EndpointConfig{ | ||
Subject: "svc.echo", | ||
Handler: micro.HandlerFunc(echoHandler), | ||
}, | ||
} | ||
for i := 0; i < 3; i++ { | ||
srv, err := micro.AddService(nc, config) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
defer srv.Stop() | ||
} | ||
``` | ||
|
||
Service IDs can be discovered by: | ||
|
||
```sh | ||
nats req '$SRV.PING.EchoService' '' --replies=3 | ||
|
||
8:59:41 Sending request on "$SRV.PING.EchoService" | ||
18:59:41 Received with rtt 688.042µs | ||
{"name":"EchoService","id":"tNoopzL5Sp1M4qJZdhdxqC","version":"1.0.0","metadata":{},"type":"io.nats.micro.v1.ping_response"} | ||
|
||
18:59:41 Received with rtt 704.167µs | ||
{"name":"EchoService","id":"tNoopzL5Sp1M4qJZdhdxvO","version":"1.0.0","metadata":{},"type":"io.nats.micro.v1.ping_response"} | ||
|
||
18:59:41 Received with rtt 707.875µs | ||
{"name":"EchoService","id":"tNoopzL5Sp1M4qJZdhdy0a","version":"1.0.0","metadata":{},"type":"io.nats.micro.v1.ping_response"} | ||
``` | ||
|
||
A specific service instance info can be retrieved: | ||
|
||
```sh | ||
nats req '$SRV.INFO.EchoService.tNoopzL5Sp1M4qJZdhdxqC' '' | ||
|
||
19:40:06 Sending request on "$SRV.INFO.EchoService.tNoopzL5Sp1M4qJZdhdxqC" | ||
19:40:06 Received with rtt 282.375µs | ||
{"name":"EchoService","id":"tNoopzL5Sp1M4qJZdhdxqC","version":"1.0.0","metadata":{},"type":"io.nats.micro.v1.info_response","description":"","subjects":["svc.echo"]} | ||
``` | ||
|
||
To get statistics for this service: | ||
|
||
```sh | ||
nats req '$SRV.STATS.EchoService.tNoopzL5Sp1M4qJZdhdxqC' '' | ||
|
||
19:40:47 Sending request on "$SRV.STATS.EchoService.tNoopzL5Sp1M4qJZdhdxqC" | ||
19:40:47 Received with rtt 421.666µs | ||
{"name":"EchoService","id":"tNoopzL5Sp1M4qJZdhdxqC","version":"1.0.0","metadata":{},"type":"io.nats.micro.v1.stats_response","started":"2023-05-22T16:59:39.938514Z","endpoints":[{"name":"default","subject":"svc.echo","metadata":null,"num_requests":0,"num_errors":0,"last_error":"","processing_time":0,"average_processing_time":0}]} | ||
``` | ||
|
||
## Examples | ||
|
||
For more detailed examples, refer to the `./test/example_test.go` directory in | ||
this package. | ||
|
||
## Documentation | ||
|
||
The complete documentation is available on | ||
[GoDoc](https://godoc.org/github.com/nats-io/nats.go/micro). |