Closed orlade-anz closed 4 years ago
conn
is used as internal property in the package.
That seems like a design bug.
Using conn
is possible because GetCompanyLocationList
is declared in the same package as GetCompanyLocationListClient
: dbendpoints
. in fact GetCompanyLocationList
is only ever implemented in a dbendpoints
test. I'm making the argument that it's not a good example.
If the impl that uses the client must be in the same package as the client, then you're preventing clients from having anything private; any internals that they need to do their job are effectively public. A workaround would be to have as fields only funcs that close over private state... but then you're fighting against the language to make the client provide a public API.
I would argue all implementation code should be in different packages to all generated/framework code to reduce the risk of leaking abstractions from private state. As such all pieces of a Client struct that are expected to be used in implementation code should be public. As per the description, I don't think the sql.Conn should be exported in general; there should be exported functions (or prepared statements) that use the conn internally to execute queries per the spec. However in situations where there are no specified queries (or an incomplete set), the implementation code should be provided with a sql.Conn to do the needful.
@andrewemeryanz for a sysl-go perspective.
The generated code that populates conn
and the developer-written code that uses it must be in different directories/packages. Therefore, access to conn
must be via exports for at least one side.
The generated servicehandler.go is given a DB describing the downstream interface. It get a conn
from that, and creates the client with it. Both the declaration of the field and the creation where the field is set are in client.arrai
, and svc_handler.arrai
uses client.new
to generate the creation code to inject into the handler. It's a bit trippy, kinda half imperative, half object oriented.
Check seems to fail because it's using the old nodiff that I fixed... not sure why it's stale.
AFAICT, the purpose of a Client is to provide the means to make downstead requests. Currently, services that have a downstream dependency on a database receive a Client with a private (non-exported) connection. This means that because the user of the Client (custom code) is in a different package to the Client (generated code), the connection is inaccessible and the Client is useless.
IIUC an ideal solution would be to specify in Sysl the queries that need to be performed on the DB, and expose the means to execute those queries as exported functions, without exposing the underlying connection. However there will be cases where a DB is needed, but the set of necessary queries is not specified, and in that case the connection itself must be exposed for the querying business logic to be implemented.