Kể từ phiên bản 1.11 chức năng go module đã được hỗ trợ. Go module là cách thức dependency management mới nhất và quan trọng mà go sẽ sử dụng cho tất cả phiên bản sau này. Mọi người nên biết và migrate sang để sử dụng go module thay vì dùng go path như cũ.
Trong bài này, mình sẽ giới thiệu go module và cách sử dụng nó.

1. Mục tiêu

Khi kết thúc bài

  • Bạn sẽ hiểu rõ về go module
  • Bạn có thể tự build 1 go package sử dụng go module

2. Yêu cầu

Để follow được bài này, bạn cần phải:

  • Có go version 1.11 trở lên cài trong máy
  • Cần 1 account github

3. Tại sao lại cần go module

Đã có rất nhiều cách thức quản lý dependency ở golang trong nhiều năm vừa qua. Nào là dep, godep, govendor và lại tiếp tục đẻ ra nhiều cái nữa, mục tiêu cũng vẫn là giải quyết cái đống hỗn loạn này 1 lần và mãi mãi.

Go module được coi là một nỗ lực chính thức để giải quyết vấn đề quản lý dependecy. Lý do chính cho việc tạo ra nó hầu như là cho phép các go developer có thể đánh version cho các go package của họ

Đánh version/ quản lý version (Semantic versioning) là một cách thức phổ biến ở các ngôn ngữ khác cho phép gắn nhãn nhiều version của nhiều app của bạn và nhiều package và nhiều library với các chữ số version. Các chữ số giống như kiểu thế này: v1.2.3, khi 1 là để chỉ ra version chính của app hay package, 2 là version phụ, còn 3 là patch version.

4. Vấn đề

Tưởng tượng rằng bạn đang phát triển một Go service mà có nhiều dependency quan trọng ví dụ như package A . Khi đó, tại thời điểm mà viết service package A có một tập interface và hoạt động theo một tập hành vi.

Tuy nhiên, điều xảy ra với người maintain package A khi update chương trình để fix bug và mở rộng chức năng là gì? Họ sẽ may mắn nếu thay đổi đó không ảnh hưởng đến phần khác ứng dụng, nhưng ngược lại, không may thì sẽ có thể crash app luôn.

Đến đây thì đánh version sẽ giải quyết vấn đề này. Bằng cách đánh version, chúng ta sẽ chọn chính xác được version của một package hay library cụ thể mà chúng ta muốn sử dụng và đảm bảo khi mà build package hay app của ta. Bài học là luôn luôn chỉ rõ ra sẽ dùng version nào.

5. Ví dụ đơn giản

Trong phần này, mình sẽ chỉ bạn cách build một go package đơn giản mà sử dụng go module để quản lý dependency.

Bắt đầu bằng cách tạo một project mới mà ta gọi là go-modules-test/

$ mkdir -p go-modules-test
$ cd go-modules-test

Tiếp theo, ta sẽ khởi tạo project để có thể sử dụng go module. Ta có thể sử dụng go mod init để khởi tạo và xác định chỗ chứa cho github repo.

$ go mod init github.com/tutorialedge/go-modules-test

Chạy xong lệnh trên thì sẽ sinh ra go.mod file, file này sẽ chứa tất cả thông tin về dependency của go app.

Khi chạy xong, hãy tạo một file mới trong phạm vi project và đặt tên là main.go

go-modules-test/main.go

package main

import "fmt"

func main() {
    fmt.Println("Hello World")
}

Sau đó chạy ứng dụng đơn giản

$ go run main.go

OUTPUT:

Hello World

6. Thêm dependency vào trong project

Bây giờ bạn đã có project cơ bản được khởi tạo và sử dụng go module, hãy tiến thêm bước nữa và xem làm thế nào để thêm các dependency vào codebase của bạn.

Theo mục tiêu của bài viết, mình sẽ sử dụng một test package github.com/elliotforbes/test-package để thực hành.

Sửa main.go thành như sau:


package main

import (
    "fmt"

    sample "github.com/elliotforbes/test-package"
)

func main() {
    fmt.Println("Hello World")
    sample.MySampleFunction()
}

Bây giờ ta đã thêm package mới vào import list, ta có thể thử sử dụng nó ngay:

$ go run main.go

OUTPUT:

go: finding github.com/elliotforbes/test-package v2.0.0
go: downloading github.com/elliotforbes/test-package v2.0.0
go: extracting github.com/elliotforbes/test-package v2.0.0
Hello World
Version 2.0 of this Function
Hello World

Amazing good job, bạn đã tự tạo một go app đơn giản mà sử dụng go module, ngoài ra còn import package khác để sử dụng rồi đấy.

7. Quản lý version

Khi app của bạn import package github.com/elliotforbes/test-package , nó sẽ mặc định import package version mới nhất để sử dụng, như đã nói best practice là luôn luôn đánh version cho mỗi package sử dụng. Vậy ta sẽ quản lý version package ở file go.mod

go.mod

module github.com/TutorialEdge/go-modules-tutorial

go 1.12

require github.com/elliotforbes/test-package v2.0.0

Một khi một lần nữa bạn thay đổi version của test-package từ v2.0.0 thành v1.0.0, bạn sẽ thấy như sau:


$ go run main.go

OUTPUT:

go: finding github.com/elliotforbes/test-package v1.0.0
go: downloading github.com/elliotforbes/test-package v1.0.0
go: extracting github.com/elliotforbes/test-package v1.0.0
Hello World
Version 1.0 of this Function
Hello World

Amazing good job, giờ đây bạn đã có thể chỉ ra chính xác version của package mà bạn sử dụng ở môi trương production. Điều này sẽ giúp ta tự tin và đảm bảo hơn khi ta release ứng dụng, và sẽ không break code khi có xự xáo trộn version và các thay đổi trong các package đó.

8. Tổng kết

Hy vọng là qua bài viết này bạn sẽ cảm thấy hữu ích và có thể xài go module ngay cho các project của mình.

9. Tham khảo

Using Go Modules