Pagoda is not a framework but rather a base starter-kit for rapid, easy full-stack web development in Go, aiming to provide much of the functionality you would expect from a complete web framework as well as establishing patterns, procedures and structure for your web application.
Built on a solid foundation of well-established frameworks and modules, Pagoda aims to be a starting point for any web application with the benefit over a mega-framework in that you have full control over all of the code, the ability to easily swap any frameworks or modules in or out, no strict patterns or interfaces to follow, and no fear of lock-in.
While separate JavaScript frontends have surged in popularity, many prefer the reliability, simplicity and speed of a full-stack approach with server-side rendered HTML. Even the popular JS frameworks all have SSR options. This project aims to highlight that Go templates can be powerful and easy to work with, and interesting frontend libraries can provide the same modern functionality and behavior without having to write any JS at all.
While many great projects were used to build this, all of which are listed in the credits section, the following provide the foundation of the back and frontend. It's important to note that you are not required to use any of these. Swapping any of them out will be relatively easy.
Go server-side rendered HTML combined with the projects below enable you to create slick, modern UIs without writing any JavaScript or CSS.
Originally, Postgres and Redis were chosen as defaults but since the aim of this project is rapid, simple development, it was changed to SQLite which now provides the primary data storage as well as persistent, background task queues. For caching, a simple in-memory solution is provided. If you need to use something like Postgres or Redis, swapping those in can be done quickly and easily. For reference, this branch contains the code that included those (but is no longer maintained).
Ensure that Go is installed on your system.
After checking out the repository, from within the root, simply run make run:
git clone git@github.com:mikestefanello/pagoda.git
cd pagoda
make run
Since this repository is a template and not a Go library, you do not use go get.
By default, you should be able to access the application in your browser at localhost:8000. This can be changed via the configuration.
By default, your data will be stored within the dbs directory. If you ever want to quickly delete all data just remove this directory.
To run all tests in the application, execute make test. This ensures that the tests from each package are not run in parallel. This is required since many packages contain tests that connect to the test database which is stored in memory and reset automatically for each package.
The container is located at pkg/services/container.go and is meant to house all of your application's services and/or dependencies. It is easily extensible and can be created and initialized in a single call. The services currently included in the container are:
A new container can be created and initialized via services.NewContainer(). It can be later shutdown via Shutdown().
The container exists to faciliate easy dependency-injection both for services within the container as well as areas of your application that require any of these dependencies. For example, the container is automatically passed to the Init() method of your route handlers so that the handlers have full, easy access to all services.
It is common that your tests will require access to dependencies, like the database, or any of the other services available within the container. Keeping all services in a container makes it especially easy to initialize everything within your tests. You can see an example pattern for doing this here.
The config package provides a flexible, extensible way to store all configuration for the application. Configuration is added to the Container as a Service, making it accessible across most of the application.
Be sure to review and adjust all of the default configuration values provided in config/config.yaml.
Leveraging the functionality of viper to manage configuration, all configuration values can be overridden by environment variables. The name of the variable is determined by the set prefix and the name of the configuration field in config/config.yaml.
In config/config.go, the prefix is set as pagoda via viper.SetEnvPrefix("pagoda"). Nested fields require an underscore between levels. For example:
http: port: 1234
can be overridden by setting an environment variable with the name PAGODA_HTTP_PORT.
The configuration value for the current environment (Config.App.Environment) is an important one as it can influence some behavior significantly (will be explained in later sections).
A helper function (config.SwitchEnvironment) is available to make switching the environment easy, but this must be executed prior to loading the configuration. The common use-case for this is to switch the environment to Test before tests are executed:
func TestMain(m *testing.M) { // Set the environment to test config.SwitchEnvironment(config.EnvTest) // Start a new container c = services.NewContainer() // Run tests exitVal := m.Run() // Shutdown the container if err := c.Shutdown(); err != nil { panic(err) } os.Exit(exitVal) }
The database currently used is SQLite but you are free to use whatever you prefer. If you plan to continue using Ent, the incredible ORM, you can check their supported databases here. The database driver is provided by go-sqlite3. A reference to the database is included in the Container if direct access is required.
Database configuration can be found and managed within the config package.
Ent provides automatic migrations which are executed on the database whenever the Container is created, which means they will run when the application starts.
Since many tests can require a database, this application supports a separate database specifically for tests. Within the config, the test database can be specified at Config.Database.TestConnection, which is the database connection string that will be used. By default, this will be an in-memory SQLite database.
When a Container is created, if the environment is set to config.EnvTest, the database client will connect to the test database instead and run migrations so your tests start with a clean, ready-to-go database.
When this project was using Postgres, it would automatically drop and recreate the test database. Since the current default is in-memory, that is no longer needed. If you decide to use a test database not in-memory, you can alter the Container initialization code to do this for you.
As previously mentioned, Ent is the supplied ORM. It can swapped out, but I highly recommend it. I don't think there is anything comparable for Go, at the current time. If you're not familiar with Ent, take a look through their top-notch documentation.
An Ent client is included in the Container to provide easy access to the ORM throughout the application.
Ent relies on code-generation for the entities you create to provide robust, type-safe data operations. Everything within the ent package in this repository is generated code for the two entity types listed below with the exception of the schema declaration.
The two included entity types are:
While you should refer to their documentation for detailed usage, it's helpful to understand how to create an entity type and generate code. To make this easier, the Makefile contains some helpers.
make ent-install.make ent-new name=User where User is the name of the entity type. This will generate a file like you can see in ent/schema/user.go though the Fields() and Edges() will be left empty.Fields() and optionally the Edges() (which are the relationships to other entity types).make ent-gen.The generated code is extremely flexible and impressive. An example to highlight this is one used within this application:
entity, err := c.ORM.PasswordToken. Query(). Where(passwordtoken.ID(tokenID)). Where(passwordtoken.HasUserWith(user.ID(userID))). Where(passwordtoken.CreatedAtGTE(expiration)). Only(ctx.Request().Context())
This executes a database query to return the password token entity with a given ID that belong to a user with a given ID and has a created at timestamp field that is greater than or equal to a given time.
Sessions are provided and handled via Gorilla sessions and configured as middleware in the router located at pkg/handlers/router.go. Session data is currently stored in cookies but there are many options available if you wish to use something else.
Here's a simple example of loading data from a session and saving new values:
func SomeFunction(ctx echo.Context) error { sess, err := session.Get(ctx, "some-session-key") if err != nil { return err } sess.Values["hello"] = "world" sess.Values["isSomething"] = true return sess.Save(ctx.Request(), ctx.Response()) }
Session data is encrypted for security purposes. The encryption key is stored in configuration at Config.App.EncryptionKey. While the default is fine for local development, it is imperative that you change this value for any live environment otherwise session data can be compromised.
Included are standard authentication features you expect in any web application. Authentication functionality is bundled as a Service within services/AuthClient and added to the Container. If you wish to handle authentication in a different manner, you could swap this client out or modify it as needed.
Authentication currently requires sessions and the session middleware.
The AuthClient has methods Login() and Logout() to log a user in or out. To track a user's authentication state, data is stored in the session including the user ID and authentication status.
Prior to logging a user in, the method CheckPassword() can be used to determine if a user's password matches the hash stored in the database and on the User entity.
Routes are provided for the


最适合小白的AI自动化工作流平台
无需编码,轻松生成可复用、可变现的AI自动化工作流

大模型驱动的Excel数据处理工具
基于大模型交互的表格处理系统,允许用户通过对话方式完成数据整理和可视化分析。系统采用机器学习算法解析用户指令,自动执行排序、公式计算和数据透视等操作,支持多种文件格式导入导出。数据处理响应速度保持在0.8秒以内,支持超过100万行数据的即时分析。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。


AI论文写作指导平台
AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。


AI一键生成PPT,就用博思AIPPT!
博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。


AI赋能电商视觉革命,一站式智能商拍平台
潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。


稳定高效的流量提升解决方案,助力品牌曝光
稳定高效的流量提升解决方案,助力品牌曝光


最新版Sora2模型免费使用,一键生成无水印视频