github.com/vmware/transport-go@v1.3.4/README.md (about)

     1  # Transport. An event bus for Go
     2  
     3  ![Transport Post-merge pipeline](https://github.com/vmware/transport-go/workflows/Transport%20Post-merge%20pipeline/badge.svg)
     4  [![codecov](https://codecov.io/gh/vmware/transport-go/branch/main/graph/badge.svg?token=BgZhsCCZ0k)](https://codecov.io/gh/vmware/transport-go)
     5  
     6  Transport is a full stack, simple, fast, expandable application event bus for your applications. It can transport anything you want around your application,
     7  as well extend different channels to brokers and destinations. Transport makes it easy to move your bits around localized or distribiuted apps, without worrying 
     8  about all the wiring.
     9  
    10  ## What does that mean?
    11  
    12  Transport is an event bus, that allows application developers to build components that can talk to one another, really easily.
    13  It provides a standardized and simple API, implemented in multiple languages, to allow any individual component inside your 
    14  applications to talk to one another.
    15  
    16  It really comes to life when you use it to send messages, requests, responses and events around your backend and front-end. 
    17  Your backend can stream messages to your UI, or other services or agents, as if they were sitting right next to each other, 
    18  You can build one to one, many to one and many to many topologies with ease.
    19  
    20  Channels can be extended to major brokers like Kafka or RabbitMQ, so Transport becomes an 'on/off-ramp' for your main sources of truth.
    21  
    22  ### Watch this quick video for an overview
    23  
    24  [![Quick Transport Overview](https://img.youtube.com/vi/k-KDPtCQyls/0.jpg)](https://www.youtube.com/watch?v=k-KDPtCQyls)
    25  
    26  ### Transport for Go also comes with plank
    27  
    28  **plank** is a micro platform for building just about anything you can think of, it exposes RESTful and AsyncAPI & Pub/Sub endpoints
    29  for services that can do just about anything. [Read more about `plank`](https://github.com/vmware/transport-go/tree/main/plank)
    30  
    31  ---
    32  
    33  ## Getting Started
    34  
    35  ### [View All Transport (Golang) Documentation](https://transport-bus.io/golang)
    36  
    37  #### Other versions of Transport
    38  
    39  - [Transport TypeScript](https://github.com/vmware/transport-typescript)
    40  - [Transport Java](https://github.com/vmware/transport-java)
    41  
    42  ### Transport Site
    43  [https://transport-bus.io](https://transport-bus.io)
    44  
    45  ---
    46  ## Quick Start
    47  
    48  Install transport 
    49  
    50  ```go
    51  go get -u github.com/vmware/transport-go
    52  ```
    53  
    54  To create an instance of the bus
    55  
    56  ```go
    57  import 	"github.com/vmware/transport-go/bus"
    58  
    59  var transport = bus.GetBus()
    60  ```
    61  > Transport is a singleton, there is (should) only ever a single instance of the bus in your application.
    62  
    63  ----
    64  
    65  ## Managing / Creating Channels
    66  
    67  The `ChannelManager` interface on the `EventBus` interface facilitates all Channel operations.
    68  
    69  ```go
    70  channelManager := transport.GetChannelManager()
    71  ```
    72  
    73  ### Creating Channels
    74  
    75  The `CreateChannel` method will create a new channel with the name "some-channel". It will return a pointer to a
    76  `Channel` object. You don't need to hold on to that pointer if you don't want to. The channel will still exist.
    77  
    78  ```go
    79  channel := channelManager.CreateChanel("some-channel")
    80  ```
    81  
    82  ## Simple Example
    83  
    84  A simple ping pong looks a little like this.
    85  
    86  ```go
    87  // listen for a single request on 'some-channel'
    88  ts := bus.GetBus()
    89  channel := "some-channel"
    90  ts.GetChannelManager().CreateChannel(channel)
    91  
    92  // listen for a single request on 'some-channel'
    93  requestHandler, _ := ts.ListenRequestStream(channel)
    94  requestHandler.Handle(
    95     func(msg *model.Message) {
    96         pingContent := msg.Payload.(string)
    97         fmt.Printf("\nPing: %s\n", pingContent)
    98  
    99         // send a response back.
   100         ts.SendResponseMessage(channel, pingContent, msg.DestinationId)
   101     },
   102     func(err error) {
   103         // something went wrong...
   104     })
   105  
   106  // send a request to 'some-channel' and handle a single response
   107  responseHandler, _ := ts.RequestOnce(channel, "Woo!")
   108  responseHandler.Handle(
   109     func(msg *model.Message) {
   110         fmt.Printf("Pong: %s\n", msg.Payload.(string))
   111     },
   112     func(err error) {
   113         // something went wrong...
   114     })
   115  // fire the request.
   116  responseHandler.Fire()
   117  ```
   118  
   119  This will output:
   120  
   121  ```text
   122  🌈 Transport booted with id [e495e5d5-2b72-46dd-8013-d49049bd4800]
   123  Ping: Woo!
   124  Pong: Woo!
   125  ```
   126  ---
   127  ## Connecting to a message broker and using galactic channels
   128  
   129  You can see this all working live in some of our interactive demos for [Transport TypeScript](https://transport-bus.io/ts/examples/joke-service).
   130  it shows Transport acting as both client and server, in which we use [`plank`](https://github.com/vmware/transport-go/tree/main/plank) to run
   131  services, and the UI subscribes to those services and talks to them.
   132  
   133  We have a live and running instance of [`plank`](https://github.com/vmware/transport-go/tree/main/plank) operating at
   134  [transport-bus.io](https://transport-bus.io). You can try the example code below to use the sample 
   135  [simple stream service](https://github.com/vmware/transport-go/blob/main/plank/services/simple-stream-service.go) and 
   136  see how simple it is for yourself.
   137  
   138  ### Simple Stream Example
   139  
   140  ```go
   141  // get a pointer to the bus.
   142  b := bus.GetBus()
   143  
   144  // get a pointer to the channel manager
   145  cm := b.GetChannelManager()
   146  
   147  // create a broker connector config and connect to 
   148  // transport-bus.io over WebSocket using TLS.
   149  config := &bridge.BrokerConnectorConfig{
   150      Username:   "guest",            // not required for demo, but our API requires it.
   151      Password:   "guest",            // ^^ same.
   152      ServerAddr: "transport-bus.io", // our live broker running plank and demo services.
   153      UseWS:      true,               // connect over websockets
   154      WebSocketConfig: &bridge.WebSocketConfig{ // configure websocket
   155          WSPath: "/ws", // websocket endpoint
   156          UseTLS: true,
   157          // use TLS/HTTPS. When using TLS, you can supply your own TLSConfig value, or we can
   158          // generate a basic one for you if you leave TLSConfig empty. In most cases, 
   159          // you won't need to supply one.
   160      }}
   161  
   162  // connect to transport-bus.io demo broker
   163  c, err := b.ConnectBroker(config)
   164  if err != nil {
   165      utils.Log.Fatalf("unable to connect to transport-bus.io, error: %v", err.Error())
   166  }
   167  
   168  // create a local channel on the bus.
   169  myLocalChan := "my-stream"
   170  cm.CreateChannel(myLocalChan)
   171  
   172  // listen to stream of messages coming in on channel, a handler is returned 
   173  // that allows you to add in lambdas that handle your success messages, and your errors.
   174  handler, _ := b.ListenStream(myLocalChan)
   175  
   176  // mark our local 'my-stream' myLocalChan as galactic and map it to our connection and 
   177  // the /topic/simple-stream service
   178  err = cm.MarkChannelAsGalactic(myLocalChan, "/topic/simple-stream", c)
   179  if err != nil {
   180      utils.Log.Fatalf("unable to map local channel to broker destination: %e", err)
   181  }
   182  
   183  // collect the streamed values in a slice
   184  var streamedValues []string
   185  
   186  // create a wait group that will wait 10 times before completing.
   187  var wg sync.WaitGroup
   188  wg.Add(10)
   189  
   190  // keep listening
   191  handler.Handle(
   192      func(msg *model.Message) {
   193  
   194          // unmarshal the message payload into a model.Response object
   195          // this is a wrapper transport uses when being used as a server, 
   196          // it encapsulates a rich set of data about the message, 
   197          // but you only really care about the payload (body)
   198          r := &model.Response{}
   199          d := msg.Payload.([]byte)
   200          err := json.Unmarshal(d, &r)
   201          if err != nil {
   202              utils.Log.Errorf("error unmarshalling request: %v", err.Error())
   203              return
   204          }
   205          // the value we want is in the payload of our model.Response
   206          value := r.Payload.(string)
   207  
   208          // log it and save it to our streamedValues
   209          utils.Log.Infof("stream ticked: %s", value)
   210          streamedValues = append(streamedValues, value)
   211          wg.Done()
   212      },
   213      func(err error) {
   214          utils.Log.Errorf("error received on channel: %e", err)
   215      })
   216  
   217  // wait for 10 ticks of the stream, then we're done.
   218  wg.Wait()
   219  
   220  // close our handler, we're done.
   221  handler.Close()
   222  
   223  // mark channel as local (unsubscribe from all mappings)
   224  err = cm.MarkChannelAsLocal(myLocalChan)
   225  if err != nil {
   226      utils.Log.Fatalf("unable to unsubscribe, error: %e", err)
   227  }
   228  
   229  // disconnect
   230  err = c.Disconnect()
   231  if err != nil {
   232      utils.Log.Fatalf("unable to disconnect, error: %e", err)
   233  }
   234  
   235  // return what we got from the stream.
   236  return streamedValues
   237  ```
   238  
   239  You can [see this simple example here](https://github.com/vmware/transport-go/blob/main/examples/simple_stream.go) 
   240  
   241  
   242  ### [Read More Golang Documentation](https://transport-bus.io/golang)
   243  
   244  ---
   245  
   246  ### [What is `plank`?](https://github.com/vmware/transport-go/tree/main/plank)
   247  
   248  `plank` is 'just enough' of a platform for building just about anything you want. Run RESTful and AsyncAPIs with the 
   249  same code, build simple or complex services that can be exposed to any client in any manner. Talk over WebSockets and pub/sub
   250  and streaming, or call the same APIs via REST mappings. `plank` can do it all. It's tiny, super-fast and runs on any platform. Runs in
   251  just a few megabytes of memory, and can be compiled down to the same. It can be used for micro-services, daemons, agents, 
   252  local UI helper applications... anything!
   253  
   254  `plank` is only available in transport-go
   255  
   256  [Take a look at plank](https://github.com/vmware/transport-go/tree/main/plank)
   257  
   258  ---
   259  ## Contributing
   260  
   261  The transport-go project team welcomes contributions from the community. Before you start working with transport-go, please
   262  read our [Developer Certificate of Origin](https://cla.vmware.com/dco). All contributions to this repository must be
   263  signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on
   264  as an open-source patch. For more detailed information, refer to [CONTRIBUTING.md](CONTRIBUTING.md).
   265  
   266  ## License
   267  BSD-2-Clause
   268  
   269  Copyright (c) 2016-2021, VMware, Inc.
   270  
   271  Redistribution and use in source and binary forms, with or without
   272  modification, are permitted provided that the following conditions are met:
   273  
   274  1. Redistributions of source code must retain the above copyright notice, this
   275     list of conditions and the following disclaimer.
   276  2. Redistributions in binary form must reproduce the above copyright notice,
   277     this list of conditions and the following disclaimer in the documentation
   278     and/or other materials provided with the distribution.
   279  
   280  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   281  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   282  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   283  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   284  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   285  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   286  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   287  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   288  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   289  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.