mirror of
https://github.com/go-gitea/gitea.git
synced 2026-06-17 19:10:22 +03:00
c68925152b
Moves the "Hacking on Gitea" page out of the documentation website and into the repository as `docs/development.md`, so contributors find build and test instructions next to the code. The content has been cleaned up and corrected for in-repo use. --------- Signed-off-by: bircni <bircni@icloud.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
133 lines
5.3 KiB
Markdown
133 lines
5.3 KiB
Markdown
# Backend development guidelines
|
|
|
|
This document covers backend-specific architecture and contribution expectations.
|
|
For the general workflow see [CONTRIBUTING.md](../CONTRIBUTING.md), and for building
|
|
and testing see [development.md](development.md) and [testing.md](testing.md).
|
|
|
|
## Background
|
|
|
|
The backend is written in Go. Web routing is handled by
|
|
[chi](https://github.com/go-chi/chi) and database access goes through the
|
|
[XORM](https://xorm.io/) ORM. Understanding how the packages depend on each other is
|
|
essential before contributing backend code.
|
|
|
|
## Package design
|
|
|
|
### Package layout
|
|
|
|
The backend is split into top-level packages, each with a focused responsibility:
|
|
|
|
- `build`: helper scripts used at compile time
|
|
- `cmd`: subcommands such as `web`, `serv`, `hooks`, `doctor`, and admin utilities
|
|
- `models`: data structures and database operations (XORM); keeps external
|
|
dependencies to a minimum
|
|
- `models/db`: core database operations
|
|
- `models/fixtures`: sample data used by tests
|
|
- `models/migrations`: schema migration scripts
|
|
- `modules`: standalone functionality with few dependencies
|
|
- `modules/setting`: configuration handling
|
|
- `modules/git`: interaction with the Git command line
|
|
- `routers`: request handlers, split into `api`, `web`, `install`, and `private`
|
|
- `services`: business logic that ties routers and models together
|
|
- `templates`: Go HTML templates
|
|
- `public`: compiled frontend assets
|
|
- `tests`: integration and end-to-end test helpers
|
|
|
|
### Dependency direction
|
|
|
|
Dependencies only flow in one direction:
|
|
|
|
```text
|
|
cmd → routers → services → models → modules
|
|
```
|
|
|
|
A package on the left may import a package on its right, but never the reverse.
|
|
|
|
### Naming conventions
|
|
|
|
- Top-level packages use the plural form: `services`, `models`, `routers`.
|
|
- Subpackages use the singular form: `services/user`, `models/repository`.
|
|
|
|
When packages from different layers share a name, use a snake_case import alias to
|
|
disambiguate:
|
|
|
|
```go
|
|
import user_service "gitea.dev/services/user"
|
|
```
|
|
|
|
### Database transactions
|
|
|
|
Operations that must roll back together should run inside `db.WithTx()` (or
|
|
`db.WithTx2()` when a value must be returned), defined in `models/db/context.go`.
|
|
Functions that participate in a transaction take a `context.Context` as their first
|
|
parameter so the transaction can be propagated.
|
|
|
|
### XORM gotchas
|
|
|
|
- Never call `x.Update(exemplar)` without an explicit `WHERE` clause — it updates
|
|
every row in the table.
|
|
- Partial table migrations must use `SyncWithOptions(IgnoreDrop...)` rather than a
|
|
plain `Sync`.
|
|
- When inserting rows with preset IDs, MSSQL requires `SET IDENTITY_INSERT` to be
|
|
enabled and PostgreSQL requires the sequence to be updated afterwards.
|
|
|
|
## Dependencies
|
|
|
|
Go dependencies are managed with [Go Modules](https://go.dev/ref/mod).
|
|
|
|
Pull requests should only modify `go.mod` and `go.sum` where it relates to the
|
|
change at hand, be it a bug fix or a new feature. Otherwise, these files should only
|
|
be touched by pull requests whose sole purpose is updating dependencies. Run
|
|
`make tidy` after any change to `go.mod`.
|
|
|
|
Any `go.mod` / `go.sum` update must be justified in the PR description and must be
|
|
verified by reviewers and the merger to reference an existing upstream commit.
|
|
|
|
## API v1
|
|
|
|
The API is documented with [Swagger](https://gitea.com/api/swagger) and is modelled
|
|
on [the GitHub API](https://docs.github.com/en/rest).
|
|
|
|
### GitHub API compatibility
|
|
|
|
Gitea's API should use the same endpoints and fields as the GitHub API where
|
|
possible, unless there is a good reason to deviate.
|
|
|
|
- If Gitea offers functionality GitHub does not, a new endpoint may be added.
|
|
- If Gitea exposes information the GitHub API does not, a new field may be added as
|
|
long as it does not collide with a GitHub field.
|
|
- Existing fields should not be removed unless there is a strong reason; the same
|
|
applies to status responses.
|
|
|
|
If you notice a problem that would require a breaking change, leave a comment in the
|
|
code for a future refactor to API v2 (which is currently not planned) rather than
|
|
breaking v1.
|
|
|
|
### Adding and maintaining API routes
|
|
|
|
- All possible results (errors, success, and failure messages) must be documented in
|
|
the swagger comments on the route.
|
|
- Every JSON request body must be defined as a struct in `modules/structs/` and
|
|
registered in [`routers/api/v1/swagger/options.go`](../routers/api/v1/swagger/options.go).
|
|
- Every JSON response must be defined as a struct in `modules/structs/` and
|
|
registered with its category under [`routers/api/v1/swagger/`](../routers/api/v1/swagger).
|
|
|
|
### HTTP methods and status codes
|
|
|
|
In general, choose HTTP methods as follows:
|
|
|
|
- **GET** returns the requested object(s) with status **200 OK**.
|
|
- **POST** creates a new object (e.g. a user) and returns **201 Created** with the
|
|
created object.
|
|
- **PUT** adds or assigns an existing object (e.g. a user to a team) and returns
|
|
**204 No Content** with no body.
|
|
- **PATCH** edits an existing object and returns the changed object with **200 OK**.
|
|
- **DELETE** removes an object and returns **204 No Content** with no body.
|
|
|
|
### Requirements for API routes
|
|
|
|
- All parameters of endpoints that edit an object must be optional, except those
|
|
needed to identify the object, which are required.
|
|
- Endpoints returning lists must support pagination (`page` and `limit` query
|
|
options) and set the `X-Total-Count` header via `ctx.SetTotalCountHeader(...)`.
|