☰ Mục lục series
Tài liệu Go tiếng Việt
  1. Bắt đầu (Getting started)
    1. Tổng quan
    2. Tải về và cài đặt
    3. Bắt đầu với Go
    4. Quản lý các bản cài đặt Go
    5. Plugin trình soạn thảo và IDE
  2. Dạo quanh Go (A Tour of Go)
    1. Chào mừng
    2. Package, biến và hàm
    3. Điều khiển luồng
    4. Struct, slice và map
    5. Method và interface
    6. Generics
    7. Xử lý đồng thời
  3. Hướng dẫn (Tutorials)
    1. Danh sách hướng dẫn
    2. Tạo một Go module
    3. Gọi mã của bạn từ một module khác
    4. Trả về và xử lý lỗi
    5. Trả về lời chào ngẫu nhiên
    6. Trả về lời chào cho nhiều người
    7. Thêm một test
    8. Biên dịch và cài đặt ứng dụng
    9. Kết luận
    10. Bắt đầu với workspace nhiều module
    11. Phát triển RESTful API với Go và Gin
    12. Truy cập cơ sở dữ liệu quan hệ
    13. Bắt đầu với generics
    14. Bắt đầu với fuzzing
    15. Làm việc với JSON
    16. Tìm và sửa các dependency có lỗ hổng với govulncheck
    17. Tìm và khắc phục phụ thuộc có lỗ hổng với VS Code Go
    18. Viết ứng dụng web
  4. Viết code Go
    1. Cách viết mã Go
    2. Effective Go
    3. Doc Comment trong Go
  5. Module
    1. Phát triển và publish module
    2. Quản lý phụ thuộc
    3. Tổ chức một module Go
    4. Quản lý mã nguồn của module
    5. Cách đánh số phiên bản module
    6. Quy trình phát hành và đánh phiên bản module
    7. Publish một module
    8. Phát triển một bản cập nhật major version
    9. Tham chiếu tệp go.mod
    10. Ngừng hỗ trợ 'go get' cho việc cài đặt tệp thực thi
  6. Cơ sở dữ liệu (Database)
    1. Truy cập cơ sở dữ liệu quan hệ
    2. Mở một handle cơ sở dữ liệu
    3. Thực thi câu lệnh SQL không trả về dữ liệu
    4. Truy vấn dữ liệu
    5. Dùng prepared statement
    6. Thực thi transaction
    7. Huỷ các thao tác đang chạy
    8. Quản lý kết nối
    9. Tránh rủi ro SQL injection
  7. Chẩn đoán và hiệu năng
    1. Chẩn đoán
    2. Hướng dẫn về Go Garbage Collector
    3. Tối ưu hoá dựa trên profile
    4. Data Race Detector
    5. Gỡ lỗi mã Go bằng GDB
    6. Hỗ trợ coverage profiling cho integration test
  8. Bảo mật (Security)
    1. Tổng quan bảo mật
    2. Thực hành tốt về bảo mật cho lập trình viên Go
    3. Quản lý lỗ hổng trong Go
    4. Cơ sở dữ liệu lỗ hổng của Go
    5. Quét lỗ hổng trong IDE
    6. Chính sách CNA của Go
    7. Go Fuzzing
    8. Chi tiết kỹ thuật của Go Fuzzing
    9. Chính sách bảo mật của Go
    10. Threat Model của Go
    11. Các quyết định về bảo mật của Go
    12. Tuân thủ FIPS 140-3
  9. Công cụ và toolchain
    1. Tài liệu về các lệnh
    2. Về lệnh go
    3. Go Toolchains
    4. Telemetry của Go
    5. Cài đặt Go từ mã nguồn
    6. Cài đặt và sử dụng gccgo
  10. Tham khảo
    1. Câu hỏi thường gặp (FAQ)
    2. Go 1 và tương lai của các chương trình Go
    3. Hướng dẫn chuyển đổi sang encoding/json/v2
    4. Hướng dẫn đóng góp
    5. Đóng góp cho frontend gccgo
  11. Phụ lục
    1. Bảng thuật ngữ
Module

Quản lý mã nguồn của module

Bản dịch từ go.dev/doc/modules/managing-source

Khi bạn phát triển module để publish cho người khác dùng, bạn có thể giúp các lập trình viên khác dùng module của mình dễ dàng hơn bằng cách tuân theo các quy ước về repository được mô tả trong bài này.

Bài này mô tả những việc bạn có thể làm khi quản lý repository chứa module của mình. Để biết trình tự các bước trong quy trình làm việc khi bạn chỉnh sửa từ phiên bản này sang phiên bản khác, xem Quy trình phát hành và đánh phiên bản module.

Một số quy ước mô tả ở đây là bắt buộc trong module, một số khác là thực hành tốt. Nội dung này giả định bạn đã quen với các cách dùng module cơ bản được mô tả trong Quản lý phụ thuộc.

Go hỗ trợ các repository sau đây để publish module: Git, Subversion, Mercurial, Bazaar và Fossil.

Để có cái nhìn tổng quan về việc phát triển module, xem Phát triển và publish module.

Cách các công cụ Go tìm thấy module bạn đã publish

Trong hệ thống phi tập trung của Go dùng để publish module và lấy mã nguồn của chúng, bạn có thể publish module mà vẫn để mã nguồn nằm trong repository của mình. Các công cụ Go dựa vào các quy tắc đặt tên, trong đó đường dẫn repository và tag của repository cho biết tên và số phiên bản của module. Khi repository của bạn tuân theo những yêu cầu này, mã nguồn module của bạn có thể được tải về từ repository bằng các công cụ Go như lệnh go get.

Khi một lập trình viên dùng lệnh go get để lấy mã nguồn cho các package mà mã của họ import, lệnh này làm những việc sau:

  1. Từ các câu lệnh import trong mã nguồn Go, go get xác định module path nằm trong đường dẫn package.
  2. Dùng một URL suy ra từ module path, lệnh này định vị mã nguồn của module trên một máy chủ proxy module hoặc trực tiếp tại repository của nó.
  3. Định vị mã nguồn của phiên bản module cần tải bằng cách khớp số phiên bản của module với một tag của repository để tìm ra mã nguồn trong repository. Khi chưa biết số phiên bản cần dùng, go get sẽ định vị bản phát hành mới nhất.
  4. Lấy mã nguồn module và tải nó về module cache cục bộ của lập trình viên.

Tổ chức mã nguồn trong repository

Bạn có thể giữ cho việc bảo trì đơn giản và cải thiện trải nghiệm của lập trình viên với module của mình bằng cách tuân theo các quy ước mô tả ở đây. Việc đưa mã nguồn module vào một repository nhìn chung cũng đơn giản như với mã nguồn khác.

Sơ đồ sau minh hoạ cây mã nguồn của một module đơn giản có hai package.

Sơ đồ minh hoạ cây mã nguồn của một module

Commit đầu tiên của bạn nên bao gồm các tệp liệt kê trong bảng sau:

Tệp Mô tả
LICENSE Giấy phép của module.
go.mod

Mô tả module, bao gồm module path của nó (thực chất là tên của nó) và các phụ thuộc của nó. Để biết thêm, xem tài liệu tham khảo go.mod.

Module path được khai báo trong một directive module, chẳng hạn:

module example.com/mymodule

Để biết thêm về cách chọn module path, xem Quản lý phụ thuộc.

Dù bạn có thể sửa trực tiếp tệp go.mod, việc thay đổi thông qua các lệnh go sẽ đáng tin cậy hơn.

go.sum

Chứa các giá trị băm mật mã đại diện cho các phụ thuộc của module. Các công cụ Go dùng những giá trị băm này để xác thực các module đã tải về, nhằm xác nhận rằng module tải về đúng là bản gốc. Khi việc xác nhận này thất bại, Go sẽ hiển thị một lỗi bảo mật.

Tệp này sẽ rỗng hoặc không tồn tại khi không có phụ thuộc nào. Bạn không nên sửa tệp này, ngoại trừ thông qua lệnh go mod tidy, lệnh này sẽ loại bỏ những mục không cần thiết.

Các thư mục package và các tệp nguồn .go. Các thư mục và tệp .go tạo nên các package Go và mã nguồn trong module.

Từ dòng lệnh, bạn có thể tạo một repository rỗng, thêm các tệp sẽ nằm trong commit đầu tiên, rồi commit kèm một thông điệp. Dưới đây là một ví dụ dùng git:

$ git init
$ git add --all
$ git commit -m "mycode: initial commit"
$ git push

Chọn phạm vi cho repository

Bạn publish mã nguồn trong một module khi mã đó cần được đánh phiên bản độc lập với mã trong các module khác.

Thiết kế repository sao cho nó chứa một module duy nhất ở thư mục gốc sẽ giúp việc bảo trì đơn giản hơn, đặc biệt là về lâu dài khi bạn publish các phiên bản minor và patch mới, tách nhánh sang major version mới, v.v. Tuy nhiên, nếu nhu cầu đòi hỏi, bạn có thể duy trì một tập hợp nhiều module trong cùng một repository.

Đặt một module trong mỗi repository

Bạn có thể duy trì một repository chỉ chứa mã nguồn của một module duy nhất. Trong mô hình này, bạn đặt tệp go.mod ở thư mục gốc của repository, còn các thư mục con của package chứa mã nguồn Go nằm bên dưới.

Đây là cách tiếp cận đơn giản nhất, giúp module của bạn nhiều khả năng dễ quản lý hơn theo thời gian. Nó giúp bạn tránh được việc phải thêm tiền tố là đường dẫn thư mục vào số phiên bản của module.

Sơ đồ minh hoạ mã nguồn của một module duy nhất trong repository của nó

Đặt nhiều module trong một repository

Bạn có thể publish nhiều module từ một repository duy nhất. Ví dụ, bạn có thể có mã nguồn trong một repository tạo thành nhiều module, nhưng lại muốn đánh phiên bản cho các module đó một cách riêng biệt.

Mỗi thư mục con là thư mục gốc của một module đều phải có tệp go.mod riêng.

Việc đặt mã nguồn module trong các thư mục con làm thay đổi dạng của tag phiên bản mà bạn phải dùng khi publish một module. Bạn phải thêm tiền tố vào phần số phiên bản của tag bằng tên thư mục con là thư mục gốc của module. Để biết thêm về số phiên bản, xem Cách đánh số phiên bản module.

Ví dụ, với module example.com/mymodules/module1 dưới đây, bạn sẽ có những thứ sau cho phiên bản v1.2.3:

  • Module path: example.com/mymodules/module1
  • Tag phiên bản: module1/v1.2.3
  • Đường dẫn package mà người dùng import: example.com/mymodules/module1/package1
  • Module path và phiên bản như được chỉ định trong directive require của người dùng: example.com/mymodules/module1 v1.2.3

Sơ đồ minh hoạ hai module trong một repository duy nhất

Nội dung gốc: Go Documentation © The Go Authors, giấy phép CC BY 3.0. Bản dịch và ghi chú: Lê Văn Dũng.