Skip to content

Instantly share code, notes, and snippets.

@samacs
Created April 1, 2019 22:47
Show Gist options
  • Save samacs/b4339a71f233b32af4468aeb29d56d8a to your computer and use it in GitHub Desktop.
Save samacs/b4339a71f233b32af4468aeb29d56d8a to your computer and use it in GitHub Desktop.
Can’t reach services through API gateway

I have a gRPC server exposing three services:

// cmd/account/main.go
func main () {
	service := micro.NewService(
		micro.Name("io.coderoso.srv.v1.account"),
	)

	accountHandler := handler.NewAccountHandler()
	proto.RegisterAccountHandler(service.Server(), accountHandler)

	authHandler := handler.NewAuthHandler()
	proto.RegisterAuthHandler(service.Server(), authHandler)

	userHandler := handler.NewUserHandler()
	proto.RegisterUserHandler(service.Server(), userService)

	if err := service.Run(); err != nil {
		log.Fatal(err)
  }
}

The service handlers are already implemented and tested with unit and integration tests using their respective clients.

My idea is now to expose those services using the API gateway. For that I have implemented a RESTful API using Gin:

// cmd/api/main.go
func main () {
	service := web.NewService(
		web.Name("io.coderoso.api.v1.account"),
	)

	accountService := proto.NewAccountService("io.coderoso.srv.v1.account", client.DefaultClient)
	authService := proto.NewAuthService("io.coderoso.srv.v1.account", client.DefaultClient)
  userService := proto.NewUserService("io.coderoso.srv.v1.account", client.DefaultClient)

  // The router is configured with the following routes:
  //
  // Account:
  //   GET    /account/:id Retrieve an account by ID.
  //   POST   /account     Create a new account.
  //
  // User:
  //   GET    /user/:id    Retrieve a user by ID.
  //   POST   /user        Create a new user.
  //
  // Auth:
  //   POST   /auth        Request a new token.
  //   DELETE /auth        Revoke an existing token.
  router := api.NewRouter(
		api.WithAccountService(accountService),
      api.WithAuthService(authService),
      api.WithUserService(userService),
	)

  service.Handle("/", router)

  if err := service.Run(); err != nil {
    log.Fatal(err)
  }
}

There is more setup in each command but was omitted for brevity.

Now when bringing all up:

$ export MICRO_REGISTRY=consul
$ export MICRO_REGISTRY_ADDRESS=localhost:8500
$ consul agent -dev
$ go run cmd/account/main.go # gRPC server
$ go run cmd/api/main.go     # API server
$ micro api --handler=http --namespace=io.coderoso.api
$ curl -v http://localhost:8080/v1/user/1
# Micro API gateway log
::1 - - [01/Apr/2019:16:29:35 -0600] "GET /v1/user/1 HTTP/1.1" 500 0 "" "curl/7.54.0"
# cURL output
> GET /v1/user/1 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Date: Mon, 01 Apr 2019 22:29:35 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
$ 

Is my understanding that given the name of the API service and the namespace set the gateway should route the request to the underlying service, which is running on a port assigned by micro: GET http://localhost:8080/v1/user/1 -> http://localhost:XXXXX/user/1

I’m afraid I’m misunderstanding or misconfiguring something but I’m following the documentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment