{"id":16092312,"url":"https://github.com/alecthomas/app","last_synced_at":"2025-03-18T06:30:56.478Z","repository":{"id":66600186,"uuid":"56848075","full_name":"alecthomas/app","owner":"alecthomas","description":"Modular application framework for Go.","archived":false,"fork":false,"pushed_at":"2023-12-02T11:57:05.000Z","size":13,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-28T07:49:35.592Z","etag":null,"topics":["app","application","framework","golang","injection","modular"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alecthomas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-22T10:37:50.000Z","updated_at":"2023-03-02T01:08:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"5561516d-b630-40ed-8393-12b5185c92f1","html_url":"https://github.com/alecthomas/app","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fapp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fapp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fapp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fapp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alecthomas","download_url":"https://codeload.github.com/alecthomas/app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243907794,"owners_count":20367286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["app","application","framework","golang","injection","modular"],"created_at":"2024-10-09T16:06:58.214Z","updated_at":"2025-03-18T06:30:56.473Z","avatar_url":"https://github.com/alecthomas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Modular application framework for Go [![](https://godoc.org/github.com/alecthomas/app?status.svg)](http://godoc.org/github.com/alecthomas/app) [![Build Status](https://travis-ci.org/alecthomas/app.png)](https://travis-ci.org/alecthomas/app) [![Gitter chat](https://badges.gitter.im/alecthomas.png)](https://gitter.im/alecthomas/Lobby)\n\nIn large monolithic code-bases, multiple applications will typically share\npackages, such as those providing core functionality such as monitoring,\nlogging, database connectors, RPC server and client configuration, etc. This\nframework allows each package to export modules that contain configuration\ndata (in the form of flags, or configurable at construction time) and logic to\ncreate objects from that package. Modules may themselves require values,\nallowing for seamless inter- dependencies, but also allowing applications to\nprovide modules with configuration (eg. a map of monitoring variables).\n\nEach application consists of a set of Modules providing features, and an\napplication module that uses those features. Types provided by modules can be\nused by other modules. Circular dependencies will be detected.\n\n*This is generally not a useful package for typical Go applications. It is\nintended for large code bases where multiple applications are composed from\nseparate modules.*\n\nIt is an opinionated framework, relying on\n[gopkg.in/alecthomas/kingpin.v3-unstable](https://gopkg.in/alecthomas/kingpin.v3-unstable)\nfor command- line management and\n[github.com/alecthomas/inject](https://github.com/alecthomas/inject)\nfor injection. See those modules for details on defining flags and implementing\nprovider methods, respectively.\n\nModules may (optionally) configure the Application instance by implementing `app.Configurable`:\n\n```go\nConfigure(app.Configurator) error\n```\n\nFlags can be configured here, but it is generally more convenient to use Kingpin's struct\nflags (see Kingpin documentation for details).\n\nIf the module has a method called `Start(...)`, it will be called with any parameters injected.\nSimilarly, any methods with a `Stop(...)` method will have it called in reverse order.\n\nUnder typical usage, packages will export modules which are composed together\nby main packages. For example:\n\n```go\npackage main\n\nimport (\n  \"gopkg.in/mgo.v2\"\n  \"github.com/alecthomas/app\"\n  \"github.com/prometheus/client_golang/prometheus\"\n\n  \"myorg/user\"\n  \"myorg/mongo\"\n  \"myorg/monitoring\"\n  \"myorg/httpserver\"\n)\n\ntype Application struct {\n  usersCreated prometheus.Counter\n  usersDeleted prometheus.Counter\n}\n\nfunc New() *Application {\n  return \u0026Application{\n    usersCreated: prometheus.NewCounter(prometheus.CounterOpts{Name: \"usersCreated\"}),\n    usersDeleted: prometheus.NewCounter(prometheus.CounterOpts{Name: \"usersDeleted\"}),\n  }\n}\n\nfunc (a *Application) Start(manager *user.UserManager) error {\n  user, err := manager.GetUser(\"alec\")\n  // Do something...\n  a.usersCreated.Inc()\n  return err\n}\n\n// Provide monitoring variables for the monitoring package to export.\nfunc (a *Application) ProvideMonitoringMapping() map[string]prometheus.Collector {\n  return map[string]prometheus.Collector{\n    \"usersCreated\": a.usersCreated,\n    \"usersDeleted\": a.usersDeleted,\n  }\n}\n\nfunc main() {\n  app.\n    Install(\n      \u0026mongo.Module{},\n      \u0026user.Module{},\n      \u0026monitoring.Module{},\n      \u0026httpserver.Module{},\n    ).\n    Run(New())\n}\n```\n\nHere's what each module might look like.\n\n```go\npackage mongo\n\nimport (\n  \"gopkg.in/mgo.v2\"\n)\n\n// Configures and provides a Mongo session.\ntype Module struct {\n  URI string `help:\"Mongo URI.\" required:\"true\"`\n  DB string `help:\"Mongo DB to connect to.\" default:\"development\"`\n}\n\nfunc (m *Module) ProvideMongoSession() (*mgo.Session, error) {\n  return mgo.Dial(m.URI)\n}\n\nfunc (m *Module) ProvideMongoDB(session *mgo.Session) *mgo.DB {\n  return session.DB(m.DB)\n}\n```\n\nThis module provides a UserManager instance. It also explicitly installs the\nMongoModule to ensure it is available. The application may also install\nMongoModule in order to configure it, if required.\n\n\n```go\npackage user\n\nimport \"myapp/mongo\"\n\n// Provide a Mongo-backed user management type.\ntype Module struct {}\n\nfunc (u *Module) Configure(config app.Configurator) error {\n  // Ensures that MongoModule is installed and required by this module.\n  config.Install(\u0026MongoModule{})\n  return nil\n}\n\nfunc (u *Module) ProvideUserManager(session *mgo.Session) (*user.UserManager, error) {\n  return New(session)\n}\n```\n\nA module for starting a HTTP server. Routes can be provided by other modules\n(see monitoring example below).\n\n```go\npackage httpserver\n\nimport (\n  \"net/http\"\n)\n\ntype Route struct {\n  Path string\n  Handler http.Handler\n}\n\ntype Module struct {\n  HTTPBind string `help:\"Bind address for HTTP server.\" default:\":8090\"`\n}\n\nfunc (m *Module) ProvideMux() *http.ServeMux {\n  return http.DefaultServeMux\n}\n\nfunc (m *Module) Start(routes []Route) error {\n  for _, route := range routes {\n    http.Handle(route.Path, route.Handler)\n  }\n  go http.ListenAndServe(m.HTTPBind, nil)\n  return nil\n}\n```\n\nThe `monitoring` module registers a set of prometheus collectors provided by\nother modules, and provides a handler for metrics collection.\n\n```go\npackage monitoring\n\nimport (\n  \"net/http\"\n\n  \"github.com/prometheus/client_golang/prometheus\"\n  \"github.com/prometheus/client_golang/prometheus/promhttp\"\n\n  \"myapp/httpserver\"\n)\n\ntype Module struct {}\n\nfunc (m *Module) Configure(config app.Configurator) error {\n  config.Install(\u0026httpserver.Module{})\n  return nil\n}\n\nfunc (m *Module) ProvideRouteSequence(collectors []prometheus.Collector) []httpserver.Route {\n  for _, collector := range collectors {\n    prometheus.MustRegister(collector)\n  }\n  return []httpserver.Route{{\"/metrics\", promhttp.Handler()}}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falecthomas%2Fapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fapp/lists"}