From 040e9833368b71479c7f4aa365d039fce9d28617 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 16 Dec 2024 22:22:19 +0800 Subject: [PATCH] up --- .../proxima-book/assets/architecture.png | Bin 0 -> 22825 bytes .../course/proxima-book/assets/coffee.jpg | Bin 0 -> 139345 bytes .../course/proxima-book/proxima-book.md | 37 +++++ ...31\344\275\234\347\272\246\345\256\232.md" | 37 +++++ ...66\346\236\204\344\273\213\347\273\215.md" | 45 ++++++ ...57\345\242\203\345\207\206\345\244\207.md" | 96 +++++++++++ ...56\345\210\235\345\247\213\345\214\226.md" | 70 ++++++++ ...54\344\271\246\346\272\220\347\240\201.md" | 33 ++++ ...72\347\241\200\344\277\241\346\201\257.md" | 10 ++ ...15\347\275\256\345\207\206\345\244\207.md" | 87 ++++++++++ ...32\345\212\241\351\200\273\350\276\221.md" | 38 +++++ ...17\350\256\256\346\226\207\344\273\266.md" | 42 +++++ ...4.\346\216\247\345\210\266\345\231\250.md" | 64 ++++++++ ...57\345\212\250\350\277\220\350\241\214.md" | 132 +++++++++++++++ ...15\345\212\241\346\263\250\345\206\214.md" | 55 +++++++ ...25\350\257\215\346\234\215\345\212\241.md" | 12 ++ ...15\347\275\256\345\207\206\345\244\207.md" | 94 +++++++++++ ...32\345\212\241\351\200\273\350\276\221.md" | 41 +++++ ...17\350\256\256\346\226\207\344\273\266.md" | 109 +++++++++++++ ...4.\346\216\247\345\210\266\345\231\250.md" | 74 +++++++++ ...57\345\212\250\350\277\220\350\241\214.md" | 152 ++++++++++++++++++ ...15\345\212\241\346\263\250\345\206\214.md" | 65 ++++++++ ...50\346\210\267\346\234\215\345\212\241.md" | 12 ++ ...21\344\270\216\345\273\272\350\256\256.md" | 25 +++ ...15\347\275\256\345\207\206\345\244\207.md" | 31 ++++ ...16\346\216\247\345\210\266\345\231\250.md" | 79 +++++++++ ...57\345\212\250\350\277\220\350\241\214.md" | 132 +++++++++++++++ ...PC\345\256\242\346\210\267\347\253\257.md" | 140 ++++++++++++++++ ...50\345\276\256\346\234\215\345\212\241.md" | 123 ++++++++++++++ ...32\345\212\241\347\275\221\345\205\263.md" | 12 ++ i18n/en/docusaurus-theme-classic/navbar.json | 4 + 31 files changed, 1851 insertions(+) create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/assets/architecture.png create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/assets/coffee.jpg create mode 100644 i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/proxima-book.md create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.1.\345\206\231\344\275\234\347\272\246\345\256\232.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.2.\346\236\266\346\236\204\344\273\213\347\273\215.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.3.\347\216\257\345\242\203\345\207\206\345\244\207.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.4.\351\241\271\347\233\256\345\210\235\345\247\213\345\214\226.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.5.\346\234\254\344\271\246\346\272\220\347\240\201.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.4.\346\216\247\345\210\266\345\231\250.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.4.\346\216\247\345\210\266\345\231\250.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\224\347\253\240-\350\277\233\344\270\200\346\255\245\347\232\204\345\255\246\344\271\240\346\226\271\345\220\221\344\270\216\345\273\272\350\256\256/\347\254\254\344\272\224\347\253\240-\350\277\233\344\270\200\346\255\245\347\232\204\345\255\246\344\271\240\346\226\271\345\220\221\344\270\216\345\273\272\350\256\256.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.2.\346\216\245\345\217\243\344\270\216\346\216\247\345\210\266\345\231\250.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.3.\345\220\257\345\212\250\350\277\220\350\241\214.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.4.gRPC\345\256\242\346\210\267\347\253\257.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.5.\350\260\203\347\224\250\345\276\256\346\234\215\345\212\241.md" create mode 100644 "i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263.md" diff --git a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/assets/architecture.png b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/assets/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..768f36554372adc9eb33338e850bd3553ec3d0ad GIT binary patch literal 22825 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

Q> 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 literal 0 HcmV?d00001 diff --git a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/proxima-book.md b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/proxima-book.md new file mode 100644 index 00000000000..6d97bb40130 --- /dev/null +++ b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/proxima-book.md @@ -0,0 +1,37 @@ +--- +slug: '/course/proxima-book' +title: 'Microservice Tutorial - Proxima Book' +hide_title: true +sidebar_position: 1 +keywords: [GoFrame, GoFrame Framework, Proxima Notebook, Microservices, gRPC, etcd, Service Registry, GoFrame Microservices, Golang Microservices, Golang Tutorial, Programming Tips, Project Development, Developer Guide, Tech Stack, Software Development, Computer Science] +description: 'This book uses the Proxima Notebook project as a practical example to help readers quickly master GoFrame microservices development. Perfect for developers who are familiar with GoFrame and want to advance into microservices development.' +--- + +## Introduction +--- +The **Proxima Notebook** is an intermediate-level practical tutorial for GoFrame. Unlike the beginner-level tutorial [Star Notebook](https://goframe.org/course/starbook), this book focuses primarily on **microservices** development. + +## Motivation +--- +Many online tutorials overwhelm readers with technical jargon, complex architectural layers, and intimidating explanations. After spending hours reading through numerous articles, developers often find themselves unable to write a single line of code. + +As the saying goes, "Hearing is not as good as seeing, seeing is not as good as doing." Hands-on practice is the best way to master microservices. This book takes you on a journey from the basics of the `GoFrame` framework to building a real microservices project, demystifying the process along the way. You'll discover that developing microservices isn't as complicated as it seems. The real complexity lies not in the development itself, but in microservices governance. + +Our goal is to share professional, practical programming tips and experiences through a project-based approach, helping you achieve real mastery! + +## Target Audience +--- +This book is designed for developers who are already familiar with `GoFrame` and want to advance their skills in microservices development. + +## Contact the Author +--- +While writing this book, some errors or omissions are inevitable. If you have any questions or suggestions, feel free to leave a comment below or contact me directly. I'll respond as soon as possible! +- Email: `tyyn1022@gmail.com` `tyyn1022@163.com` +- Website: [https://oldme.net](https://oldme.net) +- WeChat: `NobodyIsRight` (Please mention your purpose when adding) + +## Troubleshooting +--- +Encountering problems during development is normal. The key is knowing how to solve them. When facing issues, try to resolve them independently first. Consulting the `GoFrame` documentation and using search engines are excellent problem-solving approaches. If you still can't find a solution, feel free to contact me, and I'll do my best to help. + +import DocCardList from '@theme/DocCardList'; \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.1.\345\206\231\344\275\234\347\272\246\345\256\232.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.1.\345\206\231\344\275\234\347\272\246\345\256\232.md" new file mode 100644 index 00000000000..1335159a558 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.1.\345\206\231\344\275\234\347\272\246\345\256\232.md" @@ -0,0 +1,37 @@ +--- +title: '1.1 Writing Conventions' +hide_title: true +slug: '/course/proxima-book/about-convention' +keywords: [GoFrame, proxima-book, writing convention, code examples, command line usage, code simplification, microservices development] +description: "This chapter introduces the writing conventions used in the GoFrame microservices tutorial, including code simplification principles, command line usage standards, and code omission explanations to help readers better understand the tutorial content." +--- + +## Simplified Code Examples +--- +If you're reading this book, you're likely already an experienced developer. Therefore, I'll minimize unnecessary verbosity and skip non-essential code details, **focusing primarily on the microservices development process and its key features.** + +## Command Line Usage +--- +Throughout this book, I'll use the `$` symbol as a command prompt - you don't need to type this symbol. For example, if you see `$ echo "Hello, GoFrame!"`, you should only type `echo "Hello, GoFrame!"`. + +```bash +$ echo "Hello, GoFrame!" +Hello, GoFrame! +``` + +## Code Omissions +--- +To keep the content concise and clean, I'll use `...` to indicate omitted code in vertical code blocks. + +```go +package main + +import "fmt" + +... + +func main() { + fmt.Println("Hello GoFrame") +} + +... diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.2.\346\236\266\346\236\204\344\273\213\347\273\215.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.2.\346\236\266\346\236\204\344\273\213\347\273\215.md" new file mode 100644 index 00000000000..2c6b6b97648 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.2.\346\236\266\346\236\204\344\273\213\347\273\215.md" @@ -0,0 +1,45 @@ +--- +title: '1.2 Architecture Overview' +hide_title: true +slug: '/course/proxima-book/about-arch' +keywords: [GoFrame, microservices, architecture design, API gateway, user service, word service, gRPC, HTTP, load balancing, authentication] +description: "An overview of the Proxima Notebook project's microservices architecture, including the functional separation of user and word services, and the role and responsibilities of the API gateway, detailing inter-service communication methods and core gateway functions." +--- + + +The **Proxima Notebook** is a lightweight application designed to help users learn English vocabulary. It includes the following features: +- User registration +- User login +- User information queries +- Word management (CRUD operations) + +We've organized these features into logical groups, resulting in two microservices: +- User Service: Handles user registration, login, and information queries +- Word Service: Provides word-related functionality, such as CRUD operations + +Rather than exposing microservices directly, all requests are routed through an API gateway. The gateway operates as a web service that doesn't implement business logic directly. Instead, it receives requests, forwards them to appropriate microservices, and aggregates responses to complete business operations. + +The gateway's responsibilities extend beyond protocol translation, including: +- Load balancing +- Authentication and authorization +- Logging +- Monitoring +- Rate limiting + +Microservices typically communicate using either HTTP or gRPC protocols. In this project, we'll be using gRPC. + +![](../assets/architecture.png) + +## Code Repository +--- +When breaking down a monolithic service into microservices, the code naturally separates as well. There are two common approaches to managing the code repository: + +- **Multirepo:** Each microservice has its own repository. + - Advantages: Smaller, more manageable repositories + - Disadvantages: Requires additional tools and processes to coordinate dependencies and versions between services + +- **Monorepo:** All microservices code lives in a single repository. + - Advantages: Unified version and dependency management + - Disadvantages: Repository can become large and complex to manage + +Our project uses the `Monorepo` approach. The `Multirepo` approach, with its one-service-per-directory structure, is straightforward enough to not require further explanation. diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.3.\347\216\257\345\242\203\345\207\206\345\244\207.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.3.\347\216\257\345\242\203\345\207\206\345\244\207.md" new file mode 100644 index 00000000000..113db7c608b --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.3.\347\216\257\345\242\203\345\207\206\345\244\207.md" @@ -0,0 +1,96 @@ +--- +title: '1.3 Environment Setup' +hide_title: true +slug: '/course/proxima-book/about-prepare' +keywords: [GoFrame, gRPC, Protocol Buffers, development environment, installation guide, etcd, microservices tools, Go installation] +description: "A comprehensive guide to setting up the development environment for GoFrame microservices projects, including Go language configuration, GoFrame framework installation, gRPC toolchain setup, and installation instructions for related dependencies." +--- + +Don't worry if your versions differ from mine - the principles remain largely the same. + +## GoFrame +--- +We'll skip the basic installation of `Golang` and `GoFrame`. Here are the versions used in this tutorial: +- `go version go1.23.4 windows/amd64` +- `goframe v2.8.2` + +## gRPC +--- +`gRPC` is a Remote Procedure Call (RPC) framework developed by Google, built on top of HTTP/2. It uses Protocol Buffers as its default serialization format. + +Go provides gRPC functionality through the `gRPC-go` plugin. Install it using these commands: +```bash +$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest +``` + +### gRPC Testing Tools +After developing gRPC interfaces, you'll need testing tools to verify their functionality. Popular options include `Postman`, `Apifox`, and `Apipost`. They're all similar - choose the one you prefer. + +Throughout this book, we'll display test results in `json` format, like this: +```json +grpc 127.0.0.1:32001.account.v1.Account.UserRegister +{ + "username": "oldme", + "password": "123456", + "email": "tyyn1022@gmail.com" +} +{ + "id": 1 +} +``` + +These represent the request address, request parameters, and response parameters, respectively. + +## Protocol Buffers +--- +Protocol Buffers is Google's data serialization format for structured data. It uses `.proto` files to define message structures, which are then compiled into language-specific code. + +Download the appropriate version for your operating system from [Protocol Buffers Releases](https://github.com/protocolbuffers/protobuf/releases). For MacOS users, you can install dependencies using `brew`: + +```bash +$ brew install grpc protoc-gen-go protoc-gen-go-grpc +``` + +Verify the installation: +```bash +$ protoc --version +libprotoc 26.1 +``` + +## etcd +--- +etcd is a distributed key-value store commonly used for service discovery in distributed systems. There are several ways to install it. Here's a reference `docker-compose.yaml` file: + +```yaml +version: "3.7" + +services: + etcd: + image: "bitnami/etcd:3.5" + container_name: "etcd" + restart: "always" + ports: + - 2379:2379 + environment: + - TZ=Asia/Shanghai + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379 +``` + +If installed successfully, visiting [http://IP:2379/version](http://IP:2379/version) in your browser should display: +```json +{"etcdserver": "3.5.17","etcdcluster": "3.5.0"} +``` + +For a more advanced setup, like installing an etcd cluster or learning etcd basics, check out [this article](https://oldme.net/article/32). + +## Database +--- +MySQL installation is straightforward, and you can use other databases if preferred. + +Important: In a microservices architecture, each service should have its own database. We'll need to create two databases named `user` and `word`: + +```sql +CREATE DATABASE user; +CREATE DATABASE word; \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.4.\351\241\271\347\233\256\345\210\235\345\247\213\345\214\226.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.4.\351\241\271\347\233\256\345\210\235\345\247\213\345\214\226.md" new file mode 100644 index 00000000000..904aa13fa58 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.4.\351\241\271\347\233\256\345\210\235\345\247\213\345\214\226.md" @@ -0,0 +1,70 @@ +--- +title: '1.4 Project Initialization' +hide_title: true +slug: '/course/proxima-book/about-init' +keywords: [GoFrame, project initialization, Monorepo, project structure, dependency management, go.mod, microservices setup] +description: "A detailed guide on initializing a microservices project using the GoFrame CLI tool, including creating a Monorepo repository, configuring dependencies, and setting up the project structure." +--- + +## Repository Initialization +--- +Use the following command to initialize a Monorepo repository named `proxima`: + +```bash +$ gf init proxima -m +``` + +Update the minimum Go version in your environment to be compatible with GoFrame's requirements. + +*go.mod* +```text +module proxima + +go 1.23.4 +``` + +Upgrade GoFrame to the latest version: +```bash +$ cd proxima +gf up +``` + +Remove unnecessary example files: +```bash +$ rm -rf app/* +``` + +The resulting project structure will look like this: +```text +app +hack + hack.mk + hack-cli.mk +utility +go.mod +go.sum +``` + +In Monorepo mode, the root directory only manages project dependencies and doesn't contain a `main.go` file. + +The `app` directory stores code for each microservice, such as `app/user/main.go` and `app/word/main.go`. + +## Installing Microservice Components +--- +Install the `grpcx` component to enable microservice development with GoFrame: +```bash +$ go get -u github.com/gogf/gf/contrib/rpc/grpcx/v2 +``` + +## Installing Database Drivers +--- +Like monolithic applications, you'll need to install the appropriate database driver. Here we'll demonstrate using MySQL: +```bash +$ go get -u github.com/gogf/gf/contrib/drivers/mysql/v2 +``` + +## Installing etcd Components +--- +Install the `etcd` component for service registration: +```bash +$ go get -u github.com/gogf/gf/contrib/registry/etcd/v2 diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.5.\346\234\254\344\271\246\346\272\220\347\240\201.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.5.\346\234\254\344\271\246\346\272\220\347\240\201.md" new file mode 100644 index 00000000000..f8bf47a2bb3 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/1.5.\346\234\254\344\271\246\346\272\220\347\240\201.md" @@ -0,0 +1,33 @@ +--- +title: '1.5 Source Code' +hide_title: true +slug: '/course/proxima-book/about-source' +keywords: [GoFrame, source code, GitHub repository, MIT license, open source, proxima project] +description: "Access the tutorial project's source code, including the GitHub repository link and detailed information about the MIT open source license." +--- + +The source code for this book is available on [https://github.com/oldme-git/proxima](https://github.com/oldme-git/proxima). + +The project is licensed under the `MIT` License: +```text +MIT License + +Copyright (c) 2024 oldme + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257.md" new file mode 100644 index 00000000000..34d58612188 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257/\347\254\254\344\270\200\347\253\240-\345\237\272\347\241\200\344\277\241\346\201\257.md" @@ -0,0 +1,10 @@ +--- +title: 'Chapter 1 - Basic Information' +hide_title: true +sidebar_position: 1 +slug: '/course/proxima-book/about' +--- + +import DocCardList from '@theme/DocCardList'; + + diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" new file mode 100644 index 00000000000..faf896fc5d9 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" @@ -0,0 +1,87 @@ +--- +title: '3.1 Prerequisites' +hide_title: true +slug: '/course/proxima-book/word-prepare' +keywords: [GoFrame, word service setup, microservice initialization, database configuration, project structure, service preparation] +description: "A detailed guide on initializing the Word Service, including creating the service using GoFrame CLI, configuring database connections, and setting up the project structure." +--- + +After successfully implementing our first microservice, developing the second one will be more straightforward as we're now familiar with the process. + +## Code Initialization +--- +Execute the following command to create a service named `word` in the `app` directory. + +```bash +$ gf init app/word -a +initializing... +initialization done! +you can now run "cd app/word && gf run main.go" to start your journey, enjoy! +``` + +Following the same process as before, remove the following files to start with a clean environment: +```text +app/word/api/* +app/word/internal/controller/* +app/word/internal/cmd/cmd.go +``` + +Navigate to the microservice directory to begin development: +```bash +$ cd app/word +``` + +## Generating Data Models +--- +### Creating Database Tables +Execute the following SQL statement in the `word` database to create the table for storing word data: +```sql +CREATE TABLE words ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + uid INT UNSIGNED NOT NULL, + word VARCHAR ( 255 ) NOT NULL, + definition TEXT, + example_sentence TEXT, + chinese_translation VARCHAR ( 255 ), + pronunciation VARCHAR ( 255 ), + created_at DATETIME, + updated_at DATETIME +); +``` + +### Generating DAO Models +*app/user/hack/config.yaml* +```yaml +gfcli: + gen: + dao: + - link: "mysql:root:12345678@tcp(srv.com:3306)/word" + descriptionTag: true +``` + +```bash +$ gf gen dao +generated: D:\project\proxima\app\word\internal\dao\words.go +generated: D:\project\proxima\app\word\internal\dao\internal\words.go +generated: D:\project\proxima\app\word\internal\model\do\words.go +generated: D:\project\proxima\app\word\internal\model\entity\words.go +done! +``` + +### Generating Protocol Buffer Entity Models +*app/user/hack/config.yaml* +```bash +gfcli: + gen: + dao: + - link: "mysql:root:12345678@tcp(srv.com:3306)/word" + descriptionTag: true + + pbentity: + - link: "mysql:root:12345678@tcp(srv.com:3306)/word" +``` + +```bash +$ gf gen pbentity +generated: D:\project\proxima\app\word\manifest\protobuf\pbentity\words.proto +done! diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" new file mode 100644 index 00000000000..e0de1fd3074 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" @@ -0,0 +1,38 @@ +--- +title: '3.2 Business Logic' +hide_title: true +slug: /course/proxima-book/word-logic +keywords: [GoFrame, business logic, word management, CRUD operations, microservices logic, vocabulary service] +description: "This section covers the implementation of core business logic for the Word Service, including basic functionalities such as word creation and retrieval." +--- + +Similar to our previous implementation, we'll create a simple example here. + +*app/word/internal/logic/words/words.go* +```go +package words + +import ( + "context" + + "github.com/gogf/gf/v2/os/gtime" + "proxima/app/word/internal/model/entity" +) + +func Create(ctx context.Context) (id uint, err error) { + return 1, nil +} + +func Get(ctx context.Context) (word *entity.Words, err error) { + return &entity.Words{ + Id: 1, + Uid: 1, + Word: "hello", + Definition: "used as a greeting when you meet somebody.", + ExampleSentence: "Hello, I am oldme!", + ChineseTranslation: "你好", + Pronunciation: "həˈləʊ", + CreatedAt: gtime.New("2024-12-05 22:00:00"), + UpdatedAt: gtime.New("2024-12-05 22:00:00"), + }, nil +} diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" new file mode 100644 index 00000000000..0ff2c8afc63 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" @@ -0,0 +1,42 @@ +--- +title: '3.3 Protocol Files' +hide_title: true +slug: '/course/proxima-book/word-protocol' +keywords: [GoFrame, Protocol Buffers, gRPC, API definition, word service protocol, microservices communication] +description: "This section covers the Protocol Buffers protocol file definitions for the Word Service, including the design and implementation of interfaces for creating and retrieving words." +--- + +For simplicity, we'll focus on the basic `Create` and `Get` operations as examples, omitting update and delete operations. + +*app/word/manifest/protobuf/words/v1/words.proto* +```go +syntax = "proto3"; + +package words.v1; + +option go_package = "proxima/app/word/api/words/v1"; + +import "pbentity/words.proto"; + +service Words{ + rpc Create(CreateReq) returns (CreateRes) {} + rpc Get(GetReq) returns (GetRes) {} +} + +message CreateReq { + uint32 uid = 1; // v:required + string word = 2; // v:required + string definition = 3; // v:required +} + +message CreateRes { + uint32 id = 1; +} + +message GetReq { + uint32 id = 1; // v:required +} + +message GetRes { + pbentity.Words words = 1; +} \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.4.\346\216\247\345\210\266\345\231\250.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.4.\346\216\247\345\210\266\345\231\250.md" new file mode 100644 index 00000000000..23a4019e658 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.4.\346\216\247\345\210\266\345\231\250.md" @@ -0,0 +1,64 @@ +--- +title: "3.4 Controllers" +hide_title: true +slug: '/course/proxima-book/word-controller' +keywords: [GoFrame, controller generation, gRPC controller, word service controller, protobuf generation, service implementation] +description: "A comprehensive guide on generating and implementing controllers for the Word Service, including using GoFrame's code generation tools and implementing specific business logic." +--- + +Execute the following command to generate the controllers: + +```bash +$ gf gen pb +``` + +Now, let's implement the logic for the word microservice: + +*app/word/internal/controller/words/words.go* +```go +package words + +import ( + "context" + + "proxima/app/word/api/pbentity" + v1 "proxima/app/word/api/words/v1" + "proxima/app/word/internal/logic/words" + "github.com/gogf/gf/contrib/rpc/grpcx/v2" +) + +type Controller struct { + v1.UnimplementedWordsServer +} + +func Register(s *grpcx.GrpcServer) { + v1.RegisterWordsServer(s.Server, &Controller{}) +} + +func (*Controller) Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error) { + id, err := words.Create(ctx) + if err != nil { + return nil, err + } + return &v1.CreateRes{Id: uint32(id)}, nil +} + +func (*Controller) Get(ctx context.Context, req *v1.GetReq) (res *v1.GetRes, err error) { + data, err := words.Get(ctx) + if err != nil { + return nil, err + } + return &v1.GetRes{ + Words: &pbentity.Words{ + Id: uint32(data.Id), + Uid: uint32(data.Uid), + Word: data.Word, + Definition: data.Definition, + ExampleSentence: data.ExampleSentence, + ChineseTranslation: data.ChineseTranslation, + Pronunciation: data.Pronunciation, + CreatedAt: timestamppb.New(data.CreatedAt.Time), + UpdatedAt: timestamppb.New(data.CreatedAt.Time), + }, + }, nil +} diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" new file mode 100644 index 00000000000..bd6cb04f113 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" @@ -0,0 +1,132 @@ +--- +title: '3.5 Service Startup' +hide_title: true +slug: '/course/proxima-book/word-run' +keywords: [GoFrame, gRPC service, word service startup, microservices deployment, service registration, etcd integration] +description: "A comprehensive guide on starting and running the Word microservice, including service registration configuration, gRPC service setup, and health check implementation." +--- + +## Importing Controllers in CMD +--- +*app/word/internal/cmd/cmd.go* +```go +package cmd + +import ( + "context" + + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "github.com/gogf/gf/v2/os/gcmd" + "google.golang.org/grpc" + "proxima/app/word/internal/controller/words" +) + +var ( + Main = gcmd.Command{ + Name: "main", + Usage: "main", + Brief: "word grpc service", + Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { + c := grpcx.Server.NewConfig() + c.Options = append(c.Options, []grpc.ServerOption{ + grpcx.Server.ChainUnary( + grpcx.Server.UnaryValidate, + )}..., + ) + s := grpcx.Server.New(c) + words.Register(s) + s.Run() + return nil + }, + } +) +``` + +## Main Entry File +--- +Import the database driver and `cmd` in the main entry file. + +*app/user/main.go* +```go +package main + +import ( + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + + "github.com/gogf/gf/v2/os/gctx" + + "proxima/app/word/internal/cmd" +) + +func main() { + cmd.Main.Run(gctx.GetInitCtx()) +} +``` + +## Configuration File +--- +*app/user/manifest/config/config.yaml* +```yaml +grpc: + name: "word" + address: ":32002" + +database: + default: + link: "mysql:root:12345678@tcp(srv.com:3306)/word" + debug: true +``` + +## Starting the Service +--- +Ensure all dependencies are properly installed, then run the word microservice. + +```bash +$ cd app/word +build: .\main.go +go build -o .\main.exe .\main.go +.\main.exe +build running pid: 2416 +2024-12-09 15:10:40.546 [DEBU] {18cc6c8aa5700f18bf2deb5e3439664a} set default registry using file registry as no custom registry set, path: C:\Users\half\AppData\Local\Temp\gsvc +2024-12-09 15:10:40.566 [DEBU] {18cc6c8aa5700f18bf2deb5e3439664a} service register: &{Head: Deployment: Namespace: Name:word Version: Endpoints:192.168.10.98:32002 Metadata:map[protocol:grpc]} +2024-12-09 15:10:40.567 [INFO] {18cc6c8aa5700f18bf2deb5e3439664a} pid[2416]: grpc server started listening on [:32002] +``` + +With this, we've completed the development of the second microservice for Proxima Notebook. + +## Testing Results +--- +```json +grpc 127.0.0.1:32002.words.v1.Words.Create +{ + "uid": 1, + "word": "hello", + "definition": "used as a greeting when you meet somebody." +} +{ + "id": 1 +} + +grpc 127.0.0.1:32002.words.v1.Words.Get +{ + "id": 1 +} +{ + "words": { + "Id": 1, + "Uid": 1, + "Word": "hello", + "Definition": "used as a greeting when you meet somebody.", + "ExampleSentence": "Hello, I am oldme!", + "ChineseTranslation": "你好", + "Pronunciation": "həˈləʊ", + "CreatedAt": { + "seconds": "1733407200", + "nanos": 0 + }, + "UpdatedAt": { + "seconds": "1733407200", + "nanos": 0 + } + } +} diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" new file mode 100644 index 00000000000..1013ffa1cbe --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/3.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" @@ -0,0 +1,55 @@ +--- +title: '3.6 Service Registration' +hide_title: true +slug: '/course/proxima-book/word-etcd-register' +keywords: [GoFrame, etcd, service registration, word service discovery, microservices registry, configuration] +description: "Learn how to register the Word microservice with the etcd service registry, including configuration file setup and registration logic implementation." +--- + +Add the configuration file: + +*app/word/manifest/config/etcd.yaml* +```yaml +etcd: + address: "srv.com:2379" +``` + +Add the registration logic to the entry file: + +*app/word/main.go* +```go +package main + +import ( + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + + "github.com/gogf/gf/contrib/registry/etcd/v2" + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + + "proxima/app/word/internal/cmd" +) + +func main() { + var ctx = gctx.New() + conf, err := g.Cfg("etcd").Get(ctx, "etcd.address") + if err != nil { + panic(err) + } + + var address = conf.String() + grpcx.Resolver.Register(etcd.New(address)) + + cmd.Main.Run(ctx) +} +``` + +Restart the project, enter the `etcd` container again, and execute the following command to verify: +```bash +$ etcdctl get "" --prefix --keys-only +/service/default/default/user/latest/{IP}:32001 +/service/default/default/word/latest/{IP}:32002 +``` + +As we can see, both of our microservices have been successfully registered. Next, we can run the gateway to start calling these services. \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241.md" new file mode 100644 index 00000000000..43cdcfbba1a --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241/\347\254\254\344\270\211\347\253\240-\345\215\225\350\257\215\346\234\215\345\212\241.md" @@ -0,0 +1,12 @@ +--- +title: 'Chapter 3 - Word Service' +hide_title: true +sidebar_position: 3 +slug: '/course/proxima-book/word' +keywords: [GoFrame, word service, vocabulary management, microservices, CRUD operations, English learning] +description: "This chapter provides a detailed guide on implementing the Word Service using the GoFrame framework, covering core functionalities such as CRUD operations for vocabulary management and integration with other microservices." +--- + +import DocCardList from '@theme/DocCardList'; + + diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" new file mode 100644 index 00000000000..373963c4dd0 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" @@ -0,0 +1,94 @@ +--- +title: '2.1 Prerequisites' +hide_title: true +slug: '/course/proxima-book/user-overview' +keywords: [GoFrame, microservice setup, user service initialization, database configuration, project structure, service preparation] +description: "This section covers the prerequisites for the user service, including service initialization using GoFrame CLI, database configuration, and project structure setup." +--- + +Most aspects of microservice development are similar to monolithic services, and in many cases, even simpler. This chapter covers some basic preparations that should be familiar to everyone. + +## Code Initialization +--- +GoFrame provides a command for initializing microservice repositories. Execute the following command to create a service named `user` in the `app` directory. + +```bash +$ gf init app/user -a +initializing... +initialization done! +you can now run "cd app/user && gf run main.go" to start your journey, enjoy! +``` + +After successful initialization, a microservice will be created in the `app` directory. It's similar to a monolithic service, except that it lacks the `go.mod` and `go.sum` files. + +Delete the following files to start with a clean environment: +```text +app/user/api/* +app/user/internal/controller/* +app/user/internal/cmd/cmd.go +``` + +After completing these steps, enter the microservice repository to begin development. +```bash +$ cd app/user +``` + +## Database Setup +--- +### Creating Tables +In the `user` database, execute the following SQL statement to create a table for storing user data: +```sql +CREATE TABLE users ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(50) NOT NULL, + password CHAR(32) NOT NULL, + email VARCHAR(100), + created_at DATETIME, + updated_at DATETIME +); +``` + +### Generating DAO Models +*app/user/hack/config.yaml* +```yaml +gfcli: + gen: + dao: + - link: "mysql:root:12345678@tcp(srv.com:3306)/user" + descriptionTag: true +``` + +```bash +$ gf gen dao +generated: D:\project\proxima\app\user\internal\dao\users.go +generated: D:\project\proxima\app\user\internal\dao\internal\users.go +generated: D:\project\proxima\app\user\internal\model\do\users.go +generated: D:\project\proxima\app\user\internal\model\entity\users.go +done! +``` + +> Note: Execute the `gf gen dao` command in the microservice repository (i.e., the `app/user` directory). Be careful not to get this wrong. Similar rules apply to other related operations. + +### Generating Protocol Buffer Entity Models +*app/user/hack/config.yaml* +```yaml +gfcli: + gen: + dao: + - link: "mysql:root:12345678@tcp(srv.com:3306)/user" + descriptionTag: true + + pbentity: + - link: "mysql:root:12345678@tcp(srv.com:3306)/user" +``` + +```bash +$ gf gen pbentity +generated: D:\project\proxima\app\user\manifest\protobuf\pbentity\users.proto +done! +``` + +### Differences Between `gen dao` and `gen pbentity` + +- `gen dao` generates Go files primarily used within the microservice, such as for ORM operations +- `gen pbentity` generates Protocol Buffer files mainly used for gRPC communication between microservices diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" new file mode 100644 index 00000000000..89af8801467 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.2.\344\270\232\345\212\241\351\200\273\350\276\221.md" @@ -0,0 +1,41 @@ +--- +title: '2.2 Business Logic' +hide_title: true +slug: '/course/proxima-book/user-logic' +keywords: [GoFrame, business logic, user registration, account management, microservices logic, user service implementation] +description: "Detailed explanation of business logic implementation in the user service, including core functionality code implementation and best practices for user registration and management." +--- + +Like monolithic services, microservice business logic is stored in the `*/internal/logic` directory. As we're all experienced developers, I'll keep this simple and provide a basic example. + +*app/user/internal/logic/account/account.go* +```go +package account + +import ( + "context" + + "github.com/gogf/gf/v2/os/gtime" + "proxima/app/user/internal/dao" + "proxima/app/user/internal/model/entity" +) + +func Register(ctx context.Context) (id int, err error) { + return 1, nil +} + +func Login(ctx context.Context) (token string, err error) { + return "I am token", nil +} + +// Info get user info +func Info(ctx context.Context, token string) (user *entity.Users, err error) { + return &entity.Users{ + Id: 1, + Username: "oldme", + Password: "123456", + Email: "tyyn1022@gmail.com", + CreatedAt: gtime.New("2024-12-05 22:00:00"), + UpdatedAt: gtime.New("2024-12-05 22:00:00"), + }, nil +} \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" new file mode 100644 index 00000000000..bbba7a6803b --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.3.\345\215\217\350\256\256\346\226\207\344\273\266.md" @@ -0,0 +1,109 @@ +--- +title: '2.3 Protocol Files' +hide_title: true +slug: '/course/proxima-book/user-protocol' +keywords: [GoFrame, Protocol Buffers, gRPC, API definition, microservices communication, proto files, user service protocol] +description: "Introduction to Protocol Buffers protocol file definitions in the user service, including protocol design for user registration, login interfaces, and gRPC service definition best practices." +--- + +Protocol files refer to `*.proto` files. Proto is the standard communication protocol for gRPC, similar to how JSON relates to HTTP. However, it's essential to note that proto and JSON have distinct differences: proto defines both "interface" information and response/request parameters, while JSON simply stores data. + +Proto files are stored uniformly under `manifest/protobuf`, and like regular HTTP services, interface versions are managed through directory hierarchies. + +## User Registration +--- +Create a directory named `account` to manage user account-related business logic. + +*app/user/manifest/protobuf/account/v1/account.proto* +```proto +syntax = "proto3"; + +package account.v1; + +option go_package = "proxima/app/user/api/account/v1"; + +service Account{ + rpc UserRegister(UserRegisterReq) returns (UserRegisterRes) {} +} + +message UserRegisterReq { + string username = 1; // v:required|min-length:2 + string password = 2; // v:required|min-length:6 + string email = 3; // v:required|email +} + +message UserRegisterRes { + int32 id = 1; +} +``` + +Let's briefly explain the proto syntax: +- **syntax**: Specifies the file's syntax version +- **package**: Defines the service namespace, similar to a package name +- **option**: Sets compilation options; `go_package` specifies the package name for generated Go code. *In GoFrame, the fixed format is `project_name + app + microservice_name + api + module_name + v1`* +- **service**: Defines remote call methods, typically RPC, specifying request and response parameters +- **message**: Defines data structures, where `string` is the data type, `username` is the field name, and the incremental numbers after the equals sign are field numbers. *The trailing comments are framework-provided parameter validations, used similarly to regular HTTP interfaces* + +Our file defines: +- Uses proto3 syntax version +- Defines package name as `account.v1` +- Sets the Go code generation package path option `go_package` to `proxima/app/user/api/account/v1` +- Defines an `Account` service with one RPC method `UserRegister` that accepts `UserRegisterReq` message and returns `UserRegisterRes` message +- Defines a message type `UserRegisterReq` with three fields: + - `username` (string type, number 1) + - `password` (string type, number 2) + - `email` (string type, number 3) +- Defines a message type `UserRegisterRes` with one field: + - `id` (integer type, number 1) + +## User Login/Query +--- +Following the same pattern, let's define the user login and query interfaces. Here's the complete file content: + +*app/user/manifest/protobuf/account/v1/account.proto* +```proto +syntax = "proto3"; + +package account.v1; + +option go_package = "proxima/app/user/api/account/v1"; + +import "pbentity/users.proto"; + +service Account{ + rpc UserRegister(UserRegisterReq) returns (UserRegisterRes) {} + rpc UserLogin(UserLoginReq) returns (UserLoginRes) {} + rpc UserInfo(UserInfoReq) returns (UserInfoRes) {} +} + +message UserRegisterReq { + string username = 1; // v:required|min-length:2 + string password = 2; // v:required|min-length:6 + string email = 3; // v:required|email +} + +message UserRegisterRes { + int32 id = 1; +} + +message UserLoginReq { + string username = 1; // v:required|min-length:2 + string password = 2; // v:required|min-length:6 +} + +message UserLoginRes { + string token = 1; +} + +message UserInfoReq { + string token = 1; // v:required +} + +message UserInfoRes { + pbentity.Users user = 1; +} +``` + +This introduces two new syntax elements: +- `import "pbentity/users.proto"`: Imports another proto file. This file was generated by `gf gen pbentity` +- `pbentity.Users user`: Uses the imported data model, which is almost identical to Go structs \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.4.\346\216\247\345\210\266\345\231\250.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.4.\346\216\247\345\210\266\345\231\250.md" new file mode 100644 index 00000000000..06e335b015f --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.4.\346\216\247\345\210\266\345\231\250.md" @@ -0,0 +1,74 @@ +--- +title: "2.4 Controllers" +hide_title: true +slug: '/course/proxima-book/user-controller' +keywords: [GoFrame, controller generation, gRPC controller, protobuf generation, microservices controller, service implementation] +description: "A detailed guide on using GoFrame's code generation tools to generate gRPC controllers and implementing various functional interfaces for the user service." +--- + +While HTTP service controllers are generated using `gf gen ctrl`, microservices also have controllers, generated using `gf gen pb`. + +```bash +$ gf gen pb +``` + +The `gen pb` command requires all dependencies to be properly set up. When executed successfully, it generates several Go files. We only need to focus on the controller files; the framework maintains the rest. The subsequent development process is similar to HTTP services - calling `logic` functions. + +*app/user/internal/controller/account/account.go* +```go +package account + +import ( + "context" + + "google.golang.org/protobuf/types/known/timestamppb" + v1 "proxima/app/user/api/account/v1" + "proxima/app/user/api/pbentity" + "proxima/app/user/internal/logic/account" + "github.com/gogf/gf/contrib/rpc/grpcx/v2" +) + +type Controller struct { + v1.UnimplementedAccountServer +} + +func Register(s *grpcx.GrpcServer) { + v1.RegisterAccountServer(s.Server, &Controller{}) +} + +func (*Controller) UserRegister(ctx context.Context, req *v1.UserRegisterReq) (res *v1.UserRegisterRes, err error) { + id, err := account.Register(ctx) + if err != nil { + return nil, err + } + return &v1.UserRegisterRes{ + Id: int32(id), + }, nil +} + +func (*Controller) UserLogin(ctx context.Context, req *v1.UserLoginReq) (res *v1.UserLoginRes, err error) { + token, err := account.Login(ctx) + if err != nil { + return nil, err + } + return &v1.UserLoginRes{ + Token: token, + }, nil +} + +func (*Controller) UserInfo(ctx context.Context, req *v1.UserInfoReq) (res *v1.UserInfoRes, err error) { + data, err := account.Info(ctx, req.Token) + if err != nil { + return nil, err + } + return &v1.UserInfoRes{ + User: &pbentity.Users{ + Id: uint32(data.Id), + Username: data.Username, + Password: data.Password, + Email: data.Email, + CreatedAt: timestamppb.New(data.CreatedAt.Time), + UpdatedAt: timestamppb.New(data.UpdatedAt.Time), + }, + }, nil +} diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" new file mode 100644 index 00000000000..b28107bd46a --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.5.\345\220\257\345\212\250\350\277\220\350\241\214.md" @@ -0,0 +1,152 @@ +--- +title: '2.5 Service Startup' +hide_title: true +slug: '/course/proxima-book/user-run' +keywords: [GoFrame, gRPC service, service startup, microservices deployment, service registration, etcd integration] +description: "A comprehensive guide on starting and running the user microservice, including service registration, gRPC service configuration, etcd integration, and service health checks." +--- + +## Importing Controllers in CMD +--- +Like monolithic services, microservices also need to be imported in the `cmd`. The difference is that the service startup changes from `HTTP` to `gRPC`. + +*app/user/internal/cmd/cmd.go* +```go +package cmd + +import ( + "context" + + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "github.com/gogf/gf/v2/os/gcmd" + "google.golang.org/grpc" + "proxima/app/user/internal/controller/account" +) + +var ( + Main = gcmd.Command{ + Name: "main", + Usage: "main", + Brief: "user grpc service", + Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { + c := grpcx.Server.NewConfig() + c.Options = append(c.Options, []grpc.ServerOption{ + grpcx.Server.ChainUnary( + grpcx.Server.UnaryValidate, + )}..., + ) + s := grpcx.Server.New(c) + account.Register(s) + s.Run() + return nil + }, + } +) +``` + +## Main Entry File +--- +Import the database driver and `cmd` in the main entry file. + +*app/user/main.go* +```go +package main + +import ( + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + + "github.com/gogf/gf/v2/os/gctx" + + "proxima/app/user/internal/cmd" +) + +func main() { + cmd.Main.Run(gctx.GetInitCtx()) +} +``` + +## Configuration File +--- +*app/user/manifest/config/config.yaml* +```yaml +grpc: + name: "user" + address: ":32001" + +database: + default: + link: "mysql:root:12345678@tcp(srv.com:3306)/user" + debug: true +``` + +The `grpc` field defines two essential parameters: the microservice name and the listening port. The service name is used for service registration, and the listening port is self-explanatory. These two are mandatory; for other configuration options, refer to the [configuration template](https://goframe.org/docs/micro-service/config#%E9%85%8D%E7%BD%AE%E6%A8%A1%E6%9D%BF). + +## Starting the Service +--- +Switch to the root directory and ensure all dependencies are properly installed. + +```bash +$ cd ../../ +go mod tidy +``` + +Return to the microservice directory and start the user microservice. + +```bash +$ cd app/user +gf run .\main.go +build: .\main.go +go build -o .\main.exe .\main.go +.\main.exe +build running pid: 15480 +2024-12-06 15:02:01.246 [DEBU] {d8e6fef56e840e1815d0325bc73eda8f} set default registry using file registry as no custom registry set, path: C:\Users\half\AppData\Local\Temp\gsvc +2024-12-06 15:02:01.269 [DEBU] {d8e6fef56e840e1815d0325bc73eda8f} service register: &{Head: Deployment: Namespace: Name:user Version: Endpoints:192.168.10.91:32001 Metadata:map[protocol:grpc]} +2024-12-06 15:02:01.270 [INFO] {d8e6fef56e840e1815d0325bc73eda8f} pid[15480]: grpc server started listening on [:32001] +``` + +With this, we've completed the development of the first microservice for Proxima Notebook, which isn't much different from developing a monolithic service. + +## Testing Results +--- +> When testing gRPC in your testing tool, you'll need to use the proto protocol file. Make sure to specify the correct dependency paths. + +```json +grpc 127.0.0.1:32001.account.v1.Account.UserRegister +{ + "username": "oldme", + "password": "123456", + "email": "tyyn1022@gmail.com" +} +{ + "id": 1 +} + +grpc 127.0.0.1:32001.account.v1.Account.UserLogin +{ + "username": "oldme", + "password": "123456" +} +{ + "token": "I am token" +} + +grpc 127.0.0.1:32001.account.v1.Account.UserInfo +{ + "token": "I am token" +} +{ + "user": { + "Id": 1, + "Username": "oldme", + "Password": "123456", + "Email": "tyyn1022@gmail.com", + "CreatedAt": { + "seconds": "1733407200", + "nanos": 0 + }, + "UpdatedAt": { + "seconds": "1733407200", + "nanos": 0 + } + } +} diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" new file mode 100644 index 00000000000..3bde477246d --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/2.6.\346\234\215\345\212\241\346\263\250\345\206\214.md" @@ -0,0 +1,65 @@ +--- +title: '2.6 Service Registration' +hide_title: true +slug: '/course/proxima-book/user-etcd-register' +keywords: [GoFrame, etcd, service registration, service discovery, microservices registry, configuration management] +description: "A guide on registering the user microservice with etcd service registry, including configuration file setup, registration logic implementation, and service discovery mechanism configuration." +--- + +Next, we'll register the user microservice with `etcd` to make it available for other services to call. + +Add a configuration file with the `etcd` access address. + +*app/user/manifest/config/etcd.yaml* +```yaml +etcd: + address: "srv.com:2379" +``` + +Add the registration logic in the entry file: + +*app/user/main.go* +```go +package main + +import ( + _ "github.com/gogf/gf/contrib/drivers/mysql/v2" + + "github.com/gogf/gf/contrib/registry/etcd/v2" + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + + "proxima/app/user/internal/cmd" +) + +func main() { + var ctx = gctx.New() + conf, err := g.Cfg("etcd").Get(ctx, "etcd.address") + if err != nil { + panic(err) + } + + var address = conf.String() + grpcx.Resolver.Register(etcd.New(address)) + + cmd.Main.Run(ctx) +} +``` + +In fact, the key code for service registration is just one line, while the rest is code for reading the configuration file: +```go +grpcx.Resolver.Register(etcd.New(address)) +``` + +Restart the project to apply the changes. Then enter the `etcd` container and execute the following command to verify the registration: +```bash +$ etcdctl get "" --prefix --keys-only +``` + +This command shows all existing `keys` in `etcd`, where we should see our registered service: +```text +/service/default/default/user/latest/{IP}:32001 +``` + +> Service registration can be understood as similar to DNS name resolution. The service name `grpc.name` in the configuration file can be thought of as analogous to a domain name. diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241.md" new file mode 100644 index 00000000000..c1506b36b2c --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241/\347\254\254\344\272\214\347\253\240-\347\224\250\346\210\267\346\234\215\345\212\241.md" @@ -0,0 +1,12 @@ +--- +title: 'Chapter 2 - User Service' +hide_title: true +sidebar_position: 2 +slug: '/course/proxima-book/user' +keywords: [GoFrame, user service, microservices, authentication, user management, registration, login, user information] +description: "This chapter provides a detailed guide on implementing a user service using the GoFrame framework, covering core functionalities such as user registration, login, and information retrieval." +--- + +import DocCardList from '@theme/DocCardList'; + + diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\224\347\253\240-\350\277\233\344\270\200\346\255\245\347\232\204\345\255\246\344\271\240\346\226\271\345\220\221\344\270\216\345\273\272\350\256\256/\347\254\254\344\272\224\347\253\240-\350\277\233\344\270\200\346\255\245\347\232\204\345\255\246\344\271\240\346\226\271\345\220\221\344\270\216\345\273\272\350\256\256.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\224\347\253\240-\350\277\233\344\270\200\346\255\245\347\232\204\345\255\246\344\271\240\346\226\271\345\220\221\344\270\216\345\273\272\350\256\256/\347\254\254\344\272\224\347\253\240-\350\277\233\344\270\200\346\255\245\347\232\204\345\255\246\344\271\240\346\226\271\345\220\221\344\270\216\345\273\272\350\256\256.md" new file mode 100644 index 00000000000..7a1ac980fb1 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\344\272\224\347\253\240-\350\277\233\344\270\200\346\255\245\347\232\204\345\255\246\344\271\240\346\226\271\345\220\221\344\270\216\345\273\272\350\256\256/\347\254\254\344\272\224\347\253\240-\350\277\233\344\270\200\346\255\245\347\232\204\345\255\246\344\271\240\346\226\271\345\220\221\344\270\216\345\273\272\350\256\256.md" @@ -0,0 +1,25 @@ +--- +title: Chapter 5 - Further Learning and Recommendations +hide_title: true +sidebar_position: 99 +slug: /course/proxima-book/appendix +keywords: [GoFrame, microservices learning, authentication, load balancing, service configuration, interceptors, future directions] +description: "This chapter summarizes advanced learning paths for GoFrame microservices development, covering key topics such as user authentication, multi-service calls, interceptor usage, and load balancing strategies." +--- + +First, thank you to every reader who has patiently completed this book! Are your three services running smoothly, like Proxima and its two companions? +Next, here are some additional learning directions for everyone. As the author's knowledge is limited, please forgive any shortcomings. I hope your career continues to rise and flourish! + +## Further Learning Directions +--- +- User Authentication & Authorization: Enhance user authentication in microservices and implement it in the gateway service +- Multi-Service Integration: Call multiple microservices within a single controller to complete business functions +- Server-Side Interceptors: Use the gRPC server interceptors provided by `GoFrame` +- Load Balancing: Understand microservices load balancing strategies +- Service Configuration Management: Integrate with configuration centers to provide more flexible configuration options for microservices + +## Buy Me a Coffee +--- +**Thank you to all supporters!** + +![Feature List](../assets/coffee.jpg) diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" new file mode 100644 index 00000000000..ce8417426e9 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.1.\345\211\215\347\275\256\345\207\206\345\244\207.md" @@ -0,0 +1,31 @@ +--- +title: '4.1 Prerequisites' +hide_title: true +slug: '/course/proxima-book/gateway-prepare' +keywords: [GoFrame, gateway initialization, API Gateway setup, microservices gateway, project structure] +description: "A guide on initializing the API Gateway, including creating the gateway service using GoFrame CLI and setting up the project structure." +--- + +The API Gateway is similar to a monolithic web service, with the main difference being that the concrete business logic is now implemented through microservice calls. + +## Code Initialization +--- +Execute the following command to create a service named `gateway` in the `app` directory. + +```bash +$ gf init app/gateway -a +initializing... +initialization done! +you can now run "cd app/gateway && gf run main.go" to start your journey, enjoy! +``` + +Remove the following files to start with a clean environment: +```text +app/word/api/* +app/word/internal/controller/* +app/word/internal/cmd/cmd.go +``` + +Navigate to the repository to begin development: +```bash +$ cd app/gateway \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.2.\346\216\245\345\217\243\344\270\216\346\216\247\345\210\266\345\231\250.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.2.\346\216\245\345\217\243\344\270\216\346\216\247\345\210\266\345\231\250.md" new file mode 100644 index 00000000000..3f0102ca536 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.2.\346\216\245\345\217\243\344\270\216\346\216\247\345\210\266\345\231\250.md" @@ -0,0 +1,79 @@ +--- +title: "4.2 APIs and Controllers" +hide_title: true +slug: '/course/proxima-book/gateway-controller' +keywords: [GoFrame, API design, gateway controller, HTTP endpoints, request validation, response handling] +description: "A detailed guide on designing APIs and implementing controllers for the API Gateway, including the definition and request handling logic for user login, registration, and other endpoints." +--- + +This step should be familiar to everyone, so we'll keep the explanation brief. + +## API +--- +*app/gateway/api/user/v1/user.go* +```go +package v1 + +import "github.com/gogf/gf/v2/frame/g" + +type LoginReq struct { + g.Meta `path:"users/login" method:"post" sm:"Login" tags:"User"` + Username string `json:"username" v:"required|length:3,12"` + Password string `json:"password" v:"required|length:6,16"` +} + +type LoginRes struct { + Token string `json:"token" dc:"Add Authorization: token in header for authenticated endpoints"` +} +``` + +*app/gateway/api/words/v1/words.go* +```go +package v1 + +import ( + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gtime" +) + +type CreateReq struct { + g.Meta `path:"words" method:"post" sm:"Create" tags:"Word"` + Word string `json:"word" v:"required|length:1,100" dc:"Word"` + Definition string `json:"definition" v:"required|length:1,300" dc:"Word definition"` +} + +type CreateRes struct { +} + +type DetailReq struct { + g.Meta `path:"words/{id}" method:"get" sm:"Details" tags:"Word"` + Id uint `json:"id" v:"required"` +} + +type DetailRes struct { + Id uint `json:"id"` + Word string `json:"word"` + Definition string `json:"definition"` + ExampleSentence string `json:"exampleSentence"` + ChineseTranslation string `json:"chineseTranslation"` + Pronunciation string `json:"pronunciation"` + CreatedAt *gtime.Time `json:"createdAt"` + UpdatedAt *gtime.Time `json:"updatedAt"` +} +``` + +## Controller +--- +Execute the following command to generate controllers: +```bash +$ gf gen ctrl +generated: D:\project\proxima\app\gateway\api\user\user.go +generated: D:\project\proxima\app\gateway\internal\controller\user\user.go +generated: D:\project\proxima\app\gateway\internal\controller\user\user_new.go +generated: D:\project\proxima\app\gateway\internal\controller\user\user_v1_login.go +generated: D:\project\proxima\app\gateway\api\words\words.go +generated: D:\project\proxima\app\gateway\internal\controller\words\words.go +generated: D:\project\proxima\app\gateway\internal\controller\words\words_new.go +generated: D:\project\proxima\app\gateway\internal\controller\words\words_v1_create.go +generated: D:\project\proxima\app\gateway\internal\controller\words\words_v1_detail.go +done! diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.3.\345\220\257\345\212\250\350\277\220\350\241\214.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.3.\345\220\257\345\212\250\350\277\220\350\241\214.md" new file mode 100644 index 00000000000..1020ade87ee --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.3.\345\220\257\345\212\250\350\277\220\350\241\214.md" @@ -0,0 +1,132 @@ +--- +title: "4.3 Service Startup" +hide_title: true +slug: '/course/proxima-book/gateway-run' +keywords: [GoFrame, gateway configuration, service startup, HTTP server, OpenAPI, Swagger, logging setup] +description: "Detailed instructions on configuring and starting the API Gateway service, including server configuration, OpenAPI documentation, logging setup, and other key components." +--- + +Let's start by running the service before we call the microservices. + +## Configuration Files +--- +*app/gateway/manifest/config/config.yaml* +```yaml +server: + address: ":8000" + openapiPath: "/api.json" + swaggerPath: "/swagger" + logger: + path: "./log" + file: "{Y-m-d}.log" + level: "all" + stdout: true +``` + +*app/gateway/manifest/config/etcd.yaml* +```yaml +etcd: + address: "srv.com:2379" +``` + +## Command File +--- +*app/gateway/internal/cmd/cmd.go* +```go +package cmd + +import ( + "context" + + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/os/gcmd" + "proxima/app/gateway/internal/controller/user" + "proxima/app/gateway/internal/controller/words" +) + +var ( + Main = gcmd.Command{ + Name: "main", + Usage: "main", + Brief: "start http gateway server", + Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { + s := g.Server() + s.Group("/", func(group *ghttp.RouterGroup) { + group.Middleware(ghttp.MiddlewareHandlerResponse) + group.Group("/v1", func(group *ghttp.RouterGroup) { + group.Group("/", func(group *ghttp.RouterGroup) { + group.Bind(user.NewV1()) + group.Bind(words.NewV1()) + }) + }) + }) + s.Run() + return nil + }, + } +) +``` + +## Starting the Service +--- +*app/gateway/main.go* +```go +package main + +import ( + "github.com/gogf/gf/contrib/registry/etcd/v2" + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" + "proxima/app/gateway/internal/cmd" +) + +func main() { + var ctx = gctx.New() + conf, err := g.Cfg("etcd").Get(ctx, "etcd.address") + if err != nil { + panic(err) + } + + var address = conf.String() + grpcx.Resolver.Register(etcd.New(address)) + + cmd.Main.Run(ctx) +} +``` + +```bash +$ gf run .\main.go +build running pid: 16144 +2024-12-10 15:30:30.788 [INFO] pid[16144]: http server started listening on [:8000] +2024-12-10 15:30:30.788 [INFO] {f0f10d9d4ec00f181b7a6f615f39d54b} swagger ui is serving at address: http://127.0.0.1:8000/swagger/ +2024-12-10 15:30:30.789 [INFO] {f0f10d9d4ec00f181b7a6f615f39d54b} openapi specification is serving at address: http://127.0.0.1:8000/api.json +2024-12-10 15:30:30.817 [DEBU] {f0f10d9d4ec00f181b7a6f615f39d54b} service register: &{Head: Deployment: Namespace: Name:default Version: Endpoints:192.168.10.98:8000 Metadata:map[insecure:true protocol:http]} +2024-12-10 15:30:30.900 [DEBU] {f0f10d9d4ec00f181b7a6f615f39d54b} etcd put success with key "/service/default/default/default/latest/192.168.10.98:8000", value "{"insecure":true,"protocol":"http"}", lease "7587883327293376805" + + ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | ALL | /api.json | github.com/gogf/gf/v2/net/ghttp.(*Server).openapiSpec | +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | ALL | /swagger/* | github.com/gogf/gf/v2/net/ghttp.(*Server).swaggerUI | HOOK_BEFORE_SERVE +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | POST | /v1/users/login | proxima/app/gateway/internal/controller/user.(*ControllerV1).Login | +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | POST | /v1/words | proxima/app/gateway/internal/controller/words.(*ControllerV1).Create | +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + :8000 | GET | /v1/words/{id} | proxima/app/gateway/internal/controller/words.(*ControllerV1).Detail | +----------|--------|-----------------|----------------------------------------------------------------------|-------------------- + +``` + +Entering the `etcd` container and executing the command to view: +```bash +$ etcdctl get "" --prefix --keys-only + +/service/default/default/default/latest/{IP}:8000 +/service/default/default/word/latest/{IP}:32001 +/service/default/default/word/latest/{IP}:32002 +``` + +As we can see, all three of our services have been successfully registered. \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.4.gRPC\345\256\242\346\210\267\347\253\257.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.4.gRPC\345\256\242\346\210\267\347\253\257.md" new file mode 100644 index 00000000000..f29adf72b97 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.4.gRPC\345\256\242\346\210\267\347\253\257.md" @@ -0,0 +1,140 @@ +--- +title: "4.4 Implementing the gRPC Client" +hide_title: true +slug: '/course/proxima-book/gateway-client' +keywords: [GoFrame, gRPC client, microservices communication, client configuration, service discovery, etcd integration] +description: "A detailed guide on implementing and configuring gRPC clients in the API Gateway for communication with microservices, including client initialization and service discovery functionality." +--- + +## Client Implementation +--- +The API Gateway acts as a gRPC client, while each microservice acts as a gRPC server. We'll define the gRPC client in our controller properties for later use. + +The client is defined using `grpcx.Client.MustNewGrpcClientConn(service, opts...)`. + +*app/gateway/internal/controller/user/user_new.go* +```go +package user + +import ( + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "proxima/app/gateway/api/user" + v1 "proxima/app/user/api/account/v1" +) + +type ControllerV1 struct { + AccountClient v1.AccountClient +} + +func NewV1() user.IUserV1 { + var conn = grpcx.Client.MustNewGrpcClientConn("user") + + return &ControllerV1{ + AccountClient: v1.NewAccountClient(conn), + } +} +``` + +*app/gateway/internal/controller/words/words_new.go* +```go +package words + +import ( + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "proxima/app/gateway/api/words" + v1 "proxima/app/word/api/words/v1" +) + +type ControllerV1 struct { + WordsClient v1.WordsClient +} + +func NewV1() words.IWordsV1 { + var conn = grpcx.Client.MustNewGrpcClientConn("word") + + return &ControllerV1{ + WordsClient: v1.NewWordsClient(conn), + } +} +``` + +## Interceptors +--- +Currently, our client doesn't have timeout handling, and gRPC's default timeout threshold is very high. If the gRPC server, etcd service, or network encounters issues, the API Gateway could hang indefinitely. Let's add a timeout interceptor to handle these situations. + +### Defining the Interceptor +The timeout mechanism is simple, implemented using Go's context. + +*app/gateway/utility/grpc.go* +```go +package utility + +import ( + "context" + "time" + "google.golang.org/grpc" +) + +func GrpcClientTimeout(ctx context.Context, method string, req, reply interface{}, + cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption, +) error { + ctx, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + + err := invoker(ctx, method, req, reply, cc, opts...) + return err +} +``` + +### Using the Interceptor + +*app/gateway/internal/controller/user/user_new.go* +```go +package user + +import ( + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "proxima/app/gateway/api/user" + "proxima/app/gateway/utility" + v1 "proxima/app/user/api/account/v1" +) + +type ControllerV1 struct { + AccountClient v1.AccountClient +} + +func NewV1() user.IUserV1 { + var conn = grpcx.Client.MustNewGrpcClientConn("user", grpcx.Client.ChainUnary( + utility.GrpcClientTimeout, + )) + + return &ControllerV1{ + AccountClient: v1.NewAccountClient(conn), + } +} +``` + +*app/gateway/internal/controller/words/words_new.go* +```go +package words + +import ( + "github.com/gogf/gf/contrib/rpc/grpcx/v2" + "proxima/app/gateway/api/words" + "proxima/app/gateway/utility" + v1 "proxima/app/word/api/words/v1" +) + +type ControllerV1 struct { + WordsClient v1.WordsClient +} + +func NewV1() words.IWordsV1 { + var conn = grpcx.Client.MustNewGrpcClientConn("word", grpcx.Client.ChainUnary( + utility.GrpcClientTimeout, + )) + + return &ControllerV1{ + WordsClient: v1.NewWordsClient(conn), + } +} \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.5.\350\260\203\347\224\250\345\276\256\346\234\215\345\212\241.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.5.\350\260\203\347\224\250\345\276\256\346\234\215\345\212\241.md" new file mode 100644 index 00000000000..c267f597b00 --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/4.5.\350\260\203\347\224\250\345\276\256\346\234\215\345\212\241.md" @@ -0,0 +1,123 @@ +--- +title: "4.5 Calling Microservices" +hide_title: true +slug: '/course/proxima-book/gateway-call' +keywords: [GoFrame, microservices integration, service invocation, gRPC communication, gateway implementation, service orchestration] +description: "A detailed guide on integrating and calling microservices from the API Gateway, including implementations for both user and word services, and the encapsulation of business logic." +--- + +Next, we'll implement the microservices calls within our controllers to handle specific business logic. + +> In real-world development, complex business logic should be encapsulated in the `logic` layer, similar to monolithic web services, and then called by controllers. + +## User Service +--- +*app/gateway/internal/controller/user/user_v1_login.go* +```go +package user + +import ( + "context" + + account "proxima/app/user/api/account/v1" + + "proxima/app/gateway/api/user/v1" +) + +func (c *ControllerV1) Login(ctx context.Context, req *v1.LoginReq) (res *v1.LoginRes, err error) { + user, err := c.AccountClient.UserLogin(ctx, &account.UserLoginReq{ + Username: req.Username, + Password: req.Password, + }) + + if err != nil { + return nil, err + } + + return &v1.LoginRes{ + Token: user.GetToken(), + }, nil +} +``` + +Let's test the gateway-to-microservice communication with a request: +```bash +$ curl -X POST http://127.0.0.1:8000/v1/users/login \ + -H "Content-Type: application/json" \ + -d '{ + "username": "oldme", + "password": "12345678" + }' + +{ + "code": 0, + "message": "", + "data": { + "token": "I am token" + } +} +``` + +Congratulations on seeing this response! You can now try implementing the other services as well. Here's the source code for reference. + +## Word Service +--- +*app/gateway/internal/controller/words/words_v1_create.go* +```go +package words + +import ( + "context" + + words "proxima/app/word/api/words/v1" + + "proxima/app/gateway/api/words/v1" +) + +func (c *ControllerV1) Create(ctx context.Context, req *v1.CreateReq) (res *v1.CreateRes, err error) { + _, err = c.WordsClient.Create(ctx, &words.CreateReq{ + Uid: 1, + Word: req.Word, + Definition: req.Definition, + }) + + if err != nil { + return nil, err + } + + return &v1.CreateRes{}, nil +} +``` + +*app/gateway/internal/controller/words/words_v1_detail.go* +```go +package words + +import ( + "context" + + "github.com/gogf/gf/v2/errors/gerror" + words "proxima/app/word/api/words/v1" + + "proxima/app/gateway/api/words/v1" +) + +func (c *ControllerV1) Detail(ctx context.Context, req *v1.DetailReq) (res *v1.DetailRes, err error) { + word, err := c.WordsClient.Get(ctx, &words.GetReq{ + Id: uint32(req.Id), + }) + + if err != nil { + return nil, err + } + + if word == nil { + return nil, gerror.New("word not found") + } + + return &v1.DetailRes{ + Id: uint(word.Words.Id), + Word: word.Words.Word, + Definition: word.Words.Definition, + }, nil +} \ No newline at end of file diff --git "a/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263.md" "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263.md" new file mode 100644 index 00000000000..f130b4eacba --- /dev/null +++ "b/i18n/en/docusaurus-plugin-content-docs/current/course/proxima-book/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263/\347\254\254\345\233\233\347\253\240-\344\270\232\345\212\241\347\275\221\345\205\263.md" @@ -0,0 +1,12 @@ +--- +title: 'Chapter 4 - API Gateway' +hide_title: true +sidebar_position: 4 +slug: '/course/proxima-book/gateway' +keywords: [GoFrame, API Gateway, microservices gateway, service orchestration, request routing, load balancing] +description: "This chapter provides a comprehensive guide on implementing an API Gateway using the GoFrame framework, covering core functionalities such as request routing, service orchestration, and load balancing." +--- + +import DocCardList from '@theme/DocCardList'; + + diff --git a/i18n/en/docusaurus-theme-classic/navbar.json b/i18n/en/docusaurus-theme-classic/navbar.json index 0396bd985a7..5e8bf14eb57 100644 --- a/i18n/en/docusaurus-theme-classic/navbar.json +++ b/i18n/en/docusaurus-theme-classic/navbar.json @@ -34,5 +34,9 @@ "item.label.实战教程-星辰英语本": { "message": "Practical Tutorial - Star English Book", "description": "Navbar item with label 实战教程-星辰英语本" + }, + "item.label.微服务实战教程-比邻英语本": { + "message": "Microservice Tutorial - Proxima Book", + "description": "Navbar item with label 微服务实战教程-比邻英语本" } }