Skip to content

Auto-discovery of services #48

@v0idpwn

Description

@v0idpwn

Problem statement

Currently, whenever adding a new service, one must add it the reflection server module:

defmodule MyApp.Reflection.Server do
  use GrpcReflection.Server,
    version: :v1,
    services: [
      MyApp.ServiceA,
      MyApp.ServiceB,
      #...
    ]
end

This is error prone (you must remember to add every service here, and it's generally not essential for the application to work, so it's easy to forget), and in a lot of cases, it is just duplication that doesn't add much value.

Solution

The GRPC library provides reflection primitives that allow us to read all services from a given endpoint. For example:

endpoint.__meta__(:servers)
|> Enum.map(fn server ->
  service_module = server.__meta__(:service)
  service_name = service_module.__meta__(:name)
  %{server: server, service_module: service, service_name: service_name}
end)

This information can be used to optionally set a reflection server to use all services from an endpoint. Some example APIs would be:

defmodule MyApp.Reflection.Server do
  use GrpcReflection.Server,
    version: :v1,
    services: {:all, MyApp.GrpcEndpoint}
end

# Alternative without specifying the endpoint, it could read the endpoint when
# receiving the request. Might not be viable to implement in the current architecture.
defmodule MyApp.Reflection.Server do
  use GrpcReflection.Server, version: :v1
end

I'd be happy to PR if you agree.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions