github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/docs/getting-started/README.md (about)

     1  ---
     2  title: Getting Started with Micro
     3  keywords: micro
     4  tags: [micro]
     5  sidebar: home_sidebar
     6  permalink: /getting-started
     7  summary: A getting started guide for Micro
     8  ---
     9  
    10  ## Getting Started
    11  
    12  This is a getting started guide for Micro which teaches you how to go from install to helloworld and beyond.
    13  
    14  ## Contents
    15  {: .no_toc }
    16  
    17  
    18  * TOC
    19  {:toc}
    20  
    21  ## Dependencies
    22  
    23  You will need protoc-gen-micro for code generation
    24  
    25  - [protobuf](https://github.com/golang/protobuf)
    26  - [protoc-gen-go](https://github.com/golang/protobuf/tree/master/protoc-gen-go)
    27  - [protoc-gen-micro](https://github.com/tickoalcantara12/micro/tree/master/cmd/protoc-gen-micro)
    28  
    29  ```
    30  # Download latest proto releaes
    31  # https://github.com/protocolbuffers/protobuf/releases
    32  go get github.com/golang/protobuf/protoc-gen-go
    33  go get github.com/tickoalcantara12/micro/v3/cmd/protoc-gen-micro
    34  ```
    35  
    36  ## Install
    37  
    38  ### Go Get
    39  
    40  Using Go:
    41  
    42  ```sh
    43  go install github.com/tickoalcantara12/micro/v3@latest
    44  ```
    45  
    46  ### Release Binary
    47  
    48  Or by downloading the binary
    49  
    50  ```sh
    51  # MacOS
    52  curl -fsSL https://raw.githubusercontent.com/micro/micro/master/scripts/install.sh | /bin/bash
    53  
    54  # Linux
    55  wget -q  https://raw.githubusercontent.com/micro/micro/master/scripts/install.sh -O - | /bin/bash
    56  
    57  # Windows
    58  powershell -Command "iwr -useb https://raw.githubusercontent.com/micro/micro/master/scripts/install.ps1 | iex"
    59  ```
    60  
    61  ### Docker Image
    62  
    63  ```
    64  docker pull ghcr.io/micro/micro:latest
    65  ```
    66  
    67  ### Helm Chart
    68  
    69  ```
    70  helm repo add micro https://micro.github.io/helm
    71  helm install micro micro/micro
    72  ```
    73  
    74  ## Running a service
    75  
    76  Before diving into writing a service, let's run an existing one, because it's just a few commands away!
    77  
    78  
    79  First, we have to start the `micro server`. The command to do that is:
    80  
    81  ```sh
    82  micro server
    83  ```
    84  
    85  Or using docker
    86  
    87  ```
    88  sudo docker run -p 8080:8080 -p 8081:8081 ghcr.io/micro/micro:latest server
    89  ```
    90  
    91  Before interacting with the `micro server`, we need to log in with the username 'admin' and password 'micro':
    92  
    93  ```sh
    94  $ micro login
    95  Enter username: admin
    96  Enter password:
    97  Successfully logged in.
    98  ```
    99  
   100  If all goes well you'll see log output from the server listing the services as it starts them. Just to verify that everything is in order, let's see what services are running:
   101  
   102  ```sh
   103  $ micro services
   104  api
   105  auth
   106  broker
   107  config
   108  events
   109  network
   110  proxy
   111  registry
   112  runtime
   113  server
   114  store
   115  ```
   116  
   117  All those services are ones started by our `micro server`. This is pretty cool, but still it's not something we launched! Let's start a service for which existence we can actually take credit for. If we go to [github.com/micro/services](https://github.com/micro/services), we see a bunch of services written by micro authors. One of them is the `helloworld`. Try our luck, shall we?
   118  
   119  The command to run services is `micro run`.
   120  
   121  Simply issue the following command
   122  
   123  ```sh
   124  $ micro run github.com/micro/services/helloworld
   125  ```
   126  
   127  Now check the status of the running service
   128  
   129  ```sh
   130  $ micro status
   131  NAME		VERSION	SOURCE					STATUS	BUILD	UPDATED	METADATA
   132  helloworld	latest	github.com/micro/services/helloworld	running	n/a	4s ago	owner=admin, group=micro
   133  ```
   134  
   135  We can also have a look at logs of the service to verify it's running.
   136  
   137  ```sh
   138  $ micro logs helloworld
   139  2020-10-06 17:52:21  file=service/service.go:195 level=info Starting [service] helloworld
   140  2020-10-06 17:52:21  file=grpc/grpc.go:902 level=info Server [grpc] Listening on [::]:33975
   141  2020-10-06 17:52:21  file=grpc/grpc.go:732 level=info Registry [service] Registering node: helloworld-67627b23-3336-4b92-a032-09d8d13ecf95
   142  ```
   143  
   144  So since our service is running happily, let's try to call it! That's what services are for.
   145  
   146  ## Calling a service
   147  
   148  We have a couple of options to call a service running on our `micro server`.
   149  
   150  ### With the CLI
   151  
   152  Micro auto-generates CLI commands for your service in the form: `micro [service] [method]`, with the
   153  default method being "Call". Arguments can be passed as flags, hence we can call our service using:
   154  
   155  ```sh
   156  $ micro helloworld --name=Jane
   157  {
   158  	"msg": "Hello Jane"
   159  }
   160  
   161  ```
   162  
   163  That worked! If we wonder what endpoints a service has we can run the following command:
   164  
   165  ```sh
   166  $ micro helloworld --help
   167  NAME:
   168  	micro helloworld
   169  
   170  VERSION:
   171  	latest
   172  
   173  USAGE:
   174  	micro helloworld [command]
   175  
   176  COMMANDS:
   177  	call
   178  ```
   179  
   180  To see the flags for subcommands of `helloworld`:
   181  
   182  ```sh
   183  $ micro helloworld call --help
   184  NAME:
   185  	micro helloworld call
   186  
   187  USAGE:
   188  	micro helloworld call [flags]
   189  
   190  FLAGS:
   191  	--name string
   192  ```
   193  
   194  ### With the API
   195  
   196  Micro exposes a http API on port 8080 so you can just curl your service like so.
   197  
   198  ```
   199  curl "http://localhost:8080/helloworld?name=John"
   200  ```
   201  
   202  ### With the Framework
   203  
   204  Let's write a small client we can use to call the helloworld service.
   205  Normally you'll make a service call inside another service so this is just a sample of a function you may write. We'll [learn how to write a full fledged service soon](#creating-a-service).
   206  
   207  Let's take the following file:
   208  
   209  ```go
   210  package main
   211  
   212  import (
   213  	"context"
   214  	"fmt"
   215  	"time"
   216  
   217  	"github.com/tickoalcantara12/micro/v3/service"
   218  	proto "github.com/micro/services/helloworld/proto"
   219  )
   220  
   221  func main() {
   222  	// create and initialise a new service
   223  	srv := service.New()
   224  
   225  	// create the proto client for helloworld
   226  	client := proto.NewHelloworldService("helloworld", srv.Client())
   227  
   228  	// call an endpoint on the service
   229  	rsp, err := client.Call(context.Background(), &proto.CallRequest{
   230  		Name: "John",
   231  	})
   232  	if err != nil {
   233  		fmt.Println("Error calling helloworld: ", err)
   234  		return
   235  	}
   236  
   237  	// print the response
   238  	fmt.Println("Response: ", rsp.Message)
   239  	
   240  	// let's delay the process for exiting for reasons you'll see below
   241  	time.Sleep(time.Second * 5)
   242  }
   243  ```
   244  
   245  Save the example locally. For ease of following this guide, name the folder `example`.
   246  After doing a `cd example && go mod init example`, we are ready to run this service with `micro run`:
   247  
   248  ```
   249  micro run .
   250  ```
   251  
   252  `micro run`s, when successful, do not print any output. A useful command to see what is running, is `micro status`. At this point we should have two services running:
   253  
   254  ```
   255  $ micro status
   256  NAME		VERSION	SOURCE					                STATUS	BUILD	UPDATED		METADATA
   257  example		latest	example.tar.gz				            running	n/a 	2s ago		owner=admin, group=micro
   258  helloworld	latest	github.com/micro/services/helloworld	running	n/a	    5m59s ago	owner=admin, group=micro
   259  ```
   260  
   261  Now, since our example service client is also running, we should be able to see it's logs:
   262  ```sh
   263  $ micro logs example
   264  # some go build output here
   265  Response:  Hello John
   266  ```
   267  
   268  Great! That response is coming straight from the helloworld service we started earlier!
   269  
   270  ### Multi-Language Clients
   271  
   272  Soon we'll be releasing multi language grpc generated clients to query services and use micro also.
   273  
   274  ## Creating a service
   275  
   276  To create a new service, use the `micro new` command. It should output something reasonably similar to the following:
   277  
   278  ```sh
   279  $ micro new helloworld
   280  Creating service helloworld
   281  
   282  .
   283  ├── main.go
   284  ├── handler
   285  │   └── helloworld.go
   286  ├── proto
   287  │   └── helloworld.proto
   288  ├── Makefile
   289  ├── README.md
   290  ├── .gitignore
   291  └── go.mod
   292  
   293  
   294  download protoc zip packages (protoc-$VERSION-$PLATFORM.zip) and install:
   295  
   296  visit https://github.com/protocolbuffers/protobuf/releases
   297  
   298  download protobuf for micro:
   299  
   300  go get -u github.com/golang/protobuf/proto
   301  go get -u github.com/golang/protobuf/protoc-gen-go
   302  go get github.com/tickoalcantara12/micro/v3/cmd/protoc-gen-micro
   303  
   304  compile the proto file helloworld.proto:
   305  
   306  cd helloworld
   307  make proto
   308  ```
   309  
   310  As can be seen from the output above, before building the first service, the following tools must be installed:
   311  * [protoc](http://google.github.io/proto-lens/installing-protoc.html)
   312  * [protobuf/proto](github.com/golang/protobuf/protoc-gen-go)
   313  * [protoc-gen-micro](github.com/golang/protobuf/protoc-gen-go)
   314  
   315  They are all needed to translate proto files to actual Go code.
   316  Protos exist to provide a language agnostic way to describe service endpoints, their input and output types, and to have an efficient serialization format at hand.
   317  
   318  So once all tools are installed, being inside the service root, we can issue the following command to generate the Go code from the protos:
   319  
   320  ```sh
   321  make proto
   322  ```
   323  
   324  The generated code must be committed to source control, to enable other services to import the proto when making service calls (see previous section [Calling a service](#calling-a-service).
   325  
   326  At this point, we know how to write a service, run it, and call other services too.
   327  We have everything at our fingertips, but there are still some missing pieces to write applications. One of such pieces is the store interface, which helps with persistent data storage even without a database.
   328  
   329  ## Storage
   330  
   331  Amongst many other useful built-in services Micro includes a persistent storage service for storing data.
   332  
   333  ### With the CLI
   334  
   335  First, let's go over the more basic store CLI commands.
   336  
   337  To save a value, we use the write command:
   338  
   339  ```sh
   340  $ micro store write key1 val1
   341  ```
   342  
   343  The UNIX style no output meant it was happily saved. What about reading it?
   344  
   345  ```
   346  $ micro store read key1
   347  val1
   348  ```
   349  
   350  Or to display it in a fancier way, we can use the `--verbose` or `-v` flags.
   351  
   352  ```
   353  $ micro store read -v key1
   354  KEY    VALUE   EXPIRY
   355  key1   val1    None
   356  ```
   357  
   358  This view is especially useful when we use the `--prefix` or `-p` flag, which lets us search for entries which key have certain prefixes.
   359  
   360  To demonstrate that first let's save an other value:
   361  
   362  ```
   363  $ micro store write key2 val2
   364  ```
   365  
   366  After this, we can list both `key1` and `key2` keys as they both share common prefixes:
   367  
   368  ```
   369  $ micro store read --prefix --verbose key
   370  KEY    VALUE   EXPIRY
   371  key1   val1    None
   372  key2   val2    None
   373  ```
   374  
   375  There is more to the store, but this knowledge already enables us to be dangerous!
   376  
   377  ### With the Framework
   378  
   379  Accessing the same data we have just manipulated from our Go Micro services could not be easier.
   380  First let's create an entry that our service can read. This time we will specify the table for the `micro store write` command too, as each service has its own table in the store:
   381  
   382  
   383  ```
   384  micro store write --table=example mykey "Hi there"
   385  ```
   386  
   387  Let's modify [the example service we wrote previously](#calling-a-service) so instead of calling a service, it reads the above value from a store.
   388  
   389  ```go
   390  package main
   391  
   392  import (
   393  	"fmt"
   394  	"time"
   395  
   396  	"github.com/tickoalcantara12/micro/v3/service"
   397  	"github.com/tickoalcantara12/micro/v3/service/store"
   398  )
   399  
   400  func main() {
   401  	srv := service.New(service.Name("example"))
   402  	srv.Init()
   403  
   404  	records, err := store.Read("mykey", func(r *store.ReadOptions) {
   405  		r.Table = "example"
   406  	})
   407  	if err != nil {
   408  		fmt.Println("Error reading from store: ", err)
   409  	}
   410  
   411  	if len(records) == 0 {
   412  		fmt.Println("No records")
   413  	}
   414  	for _, record := range records {
   415  		fmt.Printf("key: %v, value: %v\n", record.Key, string(record.Value))
   416  	}
   417  
   418  	time.Sleep(1 * time.Hour)
   419  }
   420  ```
   421  
   422  ## Updating a service
   423  
   424  Now since the example service is running (can be easily verified by `micro status`), we should not use `micro run`, but rather `micro update` to deploy it.
   425  
   426  We can simply issue the update command (remember to switch back to the root directory of the example service first):
   427  
   428  ```sh
   429  micro update .
   430  ```
   431  
   432  And verify both with micro status:
   433  
   434  ```sh
   435  $ micro status example
   436  NAME	VERSION	SOURCE	STATUS	BUILD	UPDATED	METADATA
   437  example	latest	n/a		running	n/a		7s ago	owner=admin, group=micro
   438  ```
   439  
   440  that it was updated.
   441  
   442  If things for some reason go haywire, we can try the time tested "turning it off and on again" solution and do:
   443  
   444  ```sh
   445  micro kill example
   446  micro run .
   447  ```
   448  
   449  to start with a clean slate.
   450  
   451  So once we did update the example service, we should see the following in the logs:
   452  
   453  ```sh
   454  $ micro logs example
   455  key: mykey, value: Hi there
   456  ```
   457  
   458  ## Config
   459  
   460  Configuration and secrets is an essential part of any production system - let's see how the Micro config works.
   461  
   462  ### With the CLI
   463  
   464  The most basic example of config usage is the following:
   465  
   466  ```sh
   467  $ micro config set key val
   468  $ micro config get key
   469  val
   470  ```
   471  
   472  While this alone is enough for a great many use cases, for purposes of organisation, Micro also support dot notation of keys. Let's overwrite our keys set previously:
   473  
   474  ```sh
   475  $ micro config del key
   476  $ micro config set key.subkey val
   477  $ micro config get key.subkey
   478  val
   479  ```
   480  
   481  This is fairly straightforward, but what happens when we get `key`?
   482  
   483  ```sh
   484  $ micro config get key
   485  {"subkey":"val"}
   486  ```
   487  
   488  As it can be seen, leaf level keys will return only the value, while node level keys return the whole subtree as a JSON document:
   489  
   490  ```sh
   491  $ micro config set key.othersubkey val2
   492  $ micro config get key
   493  {"othersubkey":"val2","subkey":"val"}
   494  ```
   495  
   496  ### With the Framework
   497  
   498  Micro configs work very similarly when being called from [Go code too](https://pkg.go.dev/github.com/micro/go-micro/v3/config?tab=doc):
   499  
   500  ```go
   501  package main
   502  
   503  import (
   504  	"fmt"
   505  
   506  	"github.com/tickoalcantara12/micro/v3/service"
   507  	"github.com/tickoalcantara12/micro/v3/service/config"
   508  )
   509  
   510  func main() {
   511  	// setup the service
   512  	srv := service.New(service.Name("example"))
   513  	srv.Init()
   514  
   515  	// read config value
   516  	val, _ := config.Get("key.subkey")
   517  	fmt.Println("Value of key.subkey: ", val.String(""))
   518  }
   519  ```
   520  
   521  Assuming the folder name for this service is still `example` (to update the existing service, [see updating a service](#updating-a-service)):
   522  ```
   523  $ micro logs example
   524  Value of key.subkey:  val
   525  ```
   526  
   527  ## Further Resources
   528  
   529  This is just a brief getting started guide for quickly getting up and running with Micro. 
   530  Come back from time to time to learn more as this guide gets continually upgraded. If you're 
   531  interested in learning more Micro magic, have a look at the following sources:
   532  
   533  - Read the [docs](../)
   534  - Learn by [example](https://github.com/micro/services)