{"id":19713749,"url":"https://github.com/go-chassis/go-bmi","last_synced_at":"2025-08-31T03:32:20.375Z","repository":{"id":86510781,"uuid":"118588649","full_name":"go-chassis/go-bmi","owner":"go-chassis","description":"Body Mass Index(BMI) application developed by go-chassis microservice framwork","archived":false,"fork":false,"pushed_at":"2019-02-26T10:46:42.000Z","size":29,"stargazers_count":14,"open_issues_count":3,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-29T18:50:04.611Z","etag":null,"topics":["bmi","example","go","go-chassis","golang","microservice","service-discovery","service-registration"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/go-chassis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-23T09:33:43.000Z","updated_at":"2023-12-21T08:48:31.000Z","dependencies_parsed_at":"2023-05-01T12:05:33.469Z","dependency_job_id":null,"html_url":"https://github.com/go-chassis/go-bmi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/go-chassis/go-bmi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-chassis%2Fgo-bmi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-chassis%2Fgo-bmi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-chassis%2Fgo-bmi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-chassis%2Fgo-bmi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/go-chassis","download_url":"https://codeload.github.com/go-chassis/go-bmi/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-chassis%2Fgo-bmi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272934293,"owners_count":25017829,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-31T02:00:09.071Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bmi","example","go","go-chassis","golang","microservice","service-discovery","service-registration"],"created_at":"2024-11-11T22:24:43.334Z","updated_at":"2025-08-31T03:32:20.368Z","avatar_url":"https://github.com/go-chassis.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Develop Body Mass Index(BMI) via go-chassis\n\n\n## Prerequisite \n\n### Install Golang development environment\n\n* Install Git, details can refer to [Git Installing Guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)\n\n* Install Golang 1.11+, details can refer to [Golang Installing Guide](https://golang.org/doc/install)\n\n* Install go-chassis(SDK) by executing the following commands.\n\n   ```bash\n   mkdir -p $GOPATH/src/github.com/go-chassis\n   cd $GOPATH/src/github.com/go-chassis\n   git clone https://github.com/go-chassis/go-chassis.git\n   export GO111MODULE=on\n   go mod vendor\n   ```\n   \n### Run Service Center\n**Service Center** enables capabilities of service registration and service discovery in **ServiceComb**. It can run inside docker.\n```bash\ndocker pull servicecomb/service-center\ndocker run -d -p 30100:30100 servicecomb/service-center:latest\n```\n\n\n## Develop BMI microservice application in minutes\n\nThe workflow of BMI application have been introduced in [Quick start](/golang/quick-start/). It contains two separate microservices:\n\n- **BMI calculator service**：provides computing services.\n\n- **Web service**：provides both user interface and gateway service.\n\nNow we will introduce the detailed implementation of these two microservices. The full code is on [github](https://github.com/ServiceComb-samples/go-bmi).\n### Implementation of calculator\nThe calculator service provides capability of calculating BMI. It contains three parts:\n\n* Business logic\n\n* Service registration and configuration\n\n* Start the framework\n\n#### Business logic\n\nDefine the service structure\n```go\ntype CalculateBmi struct {\n}\n```\n\nImplement detailed calculation according to the formula \\\\(BMI=\\frac{weight}{height^2}\\\\).\n\n```go\nfunc (c *CalculateBmi) BMIIndex(height, weight float64) (float64, error) {\n\tif height \u003c= 0 || weight \u003c= 0 {\n\t\treturn 0, fmt.Errorf(\"Arugments must be above 0\")\n\t}\n\theightInMeter := height / 100\n\tbmi := weight / (heightInMeter * heightInMeter)\n\treturn bmi, nil\n}\n```\n\nWrite handler function, which must be import the parameter type of `restful.Context`. `restful.Context` contains commonly used operations on Request and Response to `http` calls. Functions starts with `Read` is about read operations from Request , including `ReadEntity` , `ReadHeader` , `ReadPathParameter` , `ReadBodyParameter` , `ReadRequest` etc .; functions start with  `Writer` is  about write operation to Response , Including `WriteHeader` , `WriteJson` , `WriteError` and so on.\n\n```go\nimport (\n  rf \"github.com/go-chassis/go-chassis/server/restful\"\n)\n\t……\nfunc (c *CalculateBmi) Calculate(b *rf.Context) {\n\t……\t\t\t\t\t//Define the Response structure, omit here \n  heightStr := b.ReadQueryParameter(\"height\")\n  weightStr := b.ReadQueryParameter(\"weight\")\n  var height, weight, bmi float64\n  var err error\n\t……  \t\t\t\t// Convert form string to float, omit here\n  if bmi, err = c.BMIIndex(height, weight); err != nil {\n    errorResponse.Error = err.Error()\n    b.WriteHeaderAndJson(http.StatusBadRequest, errorResponse, \"application/json\")\n    return\n  }\n  result.Result = bmi\n  result.CallTime = time.Now().String()\n  b.WriteJson(result, \"application/json\")   \n}\n```\nSpecify the corresponding URL route\n```go\nfunc (c *CalculateBmi) URLPatterns() []rf.Route {\n  return []rf.Route{\n    {http.MethodGet, \"/calculator/bmi\", \"Calculate\"},\n  }\n}\n```\n#### Service registration and configuration\n\nAfter the completion of the preparation of the business logic code, the business logic needs to be registered to the `Go-chassis` framework, and at the time of registration, the service name, ID and other attributes can be specified simultaneously.\n```go\n  chassis.RegisterSchema(\"rest\",\u0026CalculateBmi{})\n```\n  \nIn addition to some of the attributes specified in the code, more attributes are configured through the configuration file. The configuration file includes `chassis.yaml` and `microservice.yaml` , placed in the `conf` directory under the code directory. Among them, `chassis.yaml` contains public service properties, such as public AppId information,  registry type information, registry address, service protocol, transmission protocol information; `microservice.yaml`  is about the private properties of microservices, including the service name, version and so on.\n\n`chassis.yaml`\n    \n\n```yaml\nAPPLICATION_ID: bmi\t\t\t\t\t\t   \ncse:\n  service:\n    registry:\n      address: http://127.0.0.1:30100    \t\n  protocols:\n    rest:\n      listenAddress: 0.0.0.0:8080           \n```\n\n`microservice.yaml`\n\n```yaml\nservice_description:\n  name: calculator\t\t\t\t\t\t  \n  version: 0.0.1 \t\t\t\t\t\t  \n```\n\n#### Start the framework\n\n```go\nimport (\n  \t\"github.com/go-chassis/go-chassis\"\n\t\"github.com/go-chassis/go-chassis/core/lager\"\n)\n\t……\n  if err := chassis.Init(); err != nil {           //Init the chassis framwork\n    lager.Logger.Errorf(\"Init FAILED %s\", err.Error())\n    return\n  }\n  chassis.Run()                                     //Run the microservice\n```\n\n### Implementation of web-app service\n\nThe web service provides both the user interface . It contains three parts:\n\n* Front-end static page\n\n* Request forward\n\n* Service configuration and startup\n\n#### Front-end static page\n\nFront-end static page is powered by `Bootstrap` , and through the golang official library `http.ServeFile` front-end static page will be displayed.\n\n```go\nfunc BmiPageHandler(w http.ResponseWriter, r *http.Request) {\n  \thttp.ServeFile(w,r,\"external/index.html\")\n}\n```\n\n\n#### Request forward\n\nThe `web-app` service forwards requests to the `calculator` service via `core.NewRestInvoker()` when it receives a request from the front-end page. In the process of forwarding the call, the user does not need to know the specific address and port of the `calculator` service. The service discovery process is automatically completed by the `go-chassis` framework.\n```go\nfunc BmiRequestHandler(w http.ResponseWriter, r *http.Request) {\n  queries := r.URL.Query()\n  heightStr := queries.Get(\"height\")\n  weightStr := queries.Get(\"weight\")\n\n  requestURI := fmt.Sprintf(\"cse://calculator/bmi?height=%s\u0026weight=%s\", heightStr, weightStr)\n  restInvoker := core.NewRestInvoker()\n  req, _ := rest.NewRequest(\"GET\", requestURI)\n  resp, _ := restInvoker.ContextDo(context.TODO(), req)\n\n  w.Header().Set(\"content-type\", \"application/json\")\n  w.WriteHeader(resp.GetStatusCode())\n  w.Write(resp.ReadBody())\n}\n```\n#### Service configuration and startup\n\nThe configuration file for the `web-app` service also includes two yaml files, `chassis.yaml` and `microservice.yaml` , as follows:\n`chassis.yaml`\n\n  ```yaml\n  APPLICATION_ID: bmi\t\t\t\t\t\t\n  cse:\n    service:\n      registry:\n        address: http://127.0.0.1:30100    # ServiceCenter address\n  ```\n\n  `microservice.yaml`\n\n  ```yaml\n  service_description:\n    name: web-app\t\t\t\t\t\t\t  \n    version: 0.0.1 \t\t\t\t\t\t  \n  ```\n\nUnlike the `calculator service` , the `web-app` is a consumer-type service within the `Go-chassis` framework, so just invoke `chassis.Init()` to initialize the `Go-chassis` framework.\n\n```go\nfunc main() {\n  http.HandleFunc(\"/\", BmiPageHandler)\n  http.HandleFunc(\"/calculator/bmi\", BmiRequestHandler)\n\n  if err := chassis.Init(); err != nil {\n    lager.Logger.Errorf(\"Init FAILED %s\", err.Error())\n    return\n  }\n\n  port := flag.String(\"port\", \"8889\", \"Port web-app will listen\")\n  address := flag.String(\"address\", \"0.0.0.0\", \"Address web-app will listen\")\n  fullAddress := fmt.Sprintf(\"%s:%s\", *address, *port)\n  http.ListenAndServe(fullAddress, nil)\n}\n```\n\n### Play with kubernetes\nThe docker builds \u0026 kubernetes orchestrations are already there in the `Makefile`. There are 3 stages from binary builds to kubernetes deployments:\n- build binaries: `make $target`, for example `make calculator`, this will build the calculator binary\n- build docker images: `make docker.$target`, for example `make docker.calculator`, this will build the calculator image\n- deploy image to k8s cluster: `make k8s.$target`, for example `make k8s.calculator`, this will deploy the calculator to the kubernetes cluster by a service and a deployment\n\nHandle all by `make`:\n- `make bin`: build all the binaries\n- `make docker`: execute `make bin`, then build the docker images\n- `make k8s`: execute `make docker`, then deploy the newly built image to the kubernetes cluster\n\n\nThe k8s related make commands will call `./scripts/distribute-image.sh` to dispatch docker images to k8s clusters. The script will try to find the local IP and the k8s cluster's nodes IP, and execute some SSH command on the nodes. So there are 2 points you'll take care of:\n1. Make sure `ip` command is executable, and modify the network adapter's name in `./scripts/distribute-image.sh:25`, the default is `wlp3s0`, replace it with your local network card's name\n2. Make sure the current user has the permission to execute remote commands on the k8s cluster nodes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-chassis%2Fgo-bmi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgo-chassis%2Fgo-bmi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-chassis%2Fgo-bmi/lists"}