Say I have a service that communicates with Github via the API to create and modify repositories.
The list of functions might look something like below.
Each request made to the API has several moving parts so I split it up into multiple functions
// github_service.go
package main
// :show (GET) functions
func findGithubRepository(...)
func findGithubRepositoryRequestBuilder(...)
func findGithubRepositoryUrl(...)
// :create (POST) functions
func createGithubRepository(...)
func createGithubRepositoryPayload(...)
func createGithubRepositoryRequestBuilder(...)
func createGithubRepositoryUrl(...)
// :update (PUT) functions
func updateGithubRepository(...)
func updateGithubRepositoryPayload(...)
func updateGithubRepositoryRequestBuilder(...)
func updateGithubRepositoryUrl(...)
// Helpers used by above functions
func queryGithub(...)
func GithubHostName(...)
This layout has 2 problems -
Everything is in one big file called github_service.go
and I'm not sure how to split it up. Should it be in smaller sub-directories like services/github/update_service.go
? In general how does one organize services like this in a simple project (e.g. a command line utility)
Since all this is in the same Go package the name has to be unique. So I have namespace all the functions with the action and the context (e.g. findGithubRepositoryUrl()
instead of url()
). Should each be under a separate package?. But then how would they share common helpers?
Thanks!
You can organize your project with this structure
I have created an repository with this structure, you can clone it and use it as a template. I hope I've helped :)
There's multiple solutions to this.
type GithubRepository struct {}
func (g GithubRepository) find() {}
func (g GithubRepository) create() {}
type GithubRepositoryPayload struct {}
func (g GithubRepositoryPayload) find() {}
func (g GithubRepositoryPayload) create() {}
...
This may also give handlers a way to access to common functionality or variables. You can create a base struct with those and embed it into all of the handler structs.
For making the project simple and minimize the multiple imports of files keep all files under same package with different file names. Example (assume for testService):
repoName: testService
folder structure
1.testService(Dir)
2.routes.go
2.commons.go
2.handler.go
2.models.go
2.utils.go
1.main.go
1.Dockerfile
here numbers 1 represents that they are on same level and 2 represents files under service directory