title: Multi-tenancy in Golang
body: <p>I'm currently writing a service in Go where I need to deal with multiple tenants. I have settled on using the one database, shared-tables approach using a 'tenant_id' decriminator for tenant separation.</p>
  
  <p>The service is structured like this:</p>
  
  <pre><code>gRPC server -&gt; gRPC Handlers -
                                \_ Managers (SQL)
                                /
  HTTP/JSON server -&gt; Handlers -
  </code></pre>
  
  <p>Two servers, one gRPC (administration) and one HTTP/JSON (public API), each running in their own go-routine and with their own respective handlers that can make use of the functionality of the different managers. The managers (lets call one 'inventory-manager'), all lives in different root-level packages. These are as far as I understand it my domain entities.</p>
  
  <p>In this regard I have some questions:</p>
  
  <ol>
  <li><p>I cannot find any ORM for Go that supports multiple tenants out there. Is writing my own on top of perhaps the sqlx package a valid option?</p></li>
  <li><p>Other services in the future will require multi-tenant support too, so I guess I would have to create some library/package anyway.</p></li>
  <li><p>Today, I resolve the tenants by using a ResolveTenantBySubdomain middleware for the public API server. I then place the resolved tenant id in a context value that is sent with the call to the manager. Inside the different methods in the manager, I get the tenant id from the context value. This is then used with every SQL query/exec calls or returns a error if missing or invalid tenant id. Should I even use context for this purpose?</p></li>
  <li><p>Resolving the tenant on the gRPC server, I believe I have to use the UnaryInterceptor function for middleware handling. Since the gRPC 
  API interface will only be accessed by other backend services, i guess resolving by subdomain is unneccessary here. But how should I embed the tenant id? In the header? </p></li>
  </ol>
  
  <p>Really hope I'm asking the right questions.
  Regards, Karl.</p>