@ticket_for_cinema/contracts 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/gen/auth.ts +50 -0
- package/package.json +22 -0
- package/proto/auth.proto +17 -0
- package/proto/redme.md +521 -0
package/gen/auth.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
|
+
// versions:
|
|
3
|
+
// protoc-gen-ts_proto v1.181.2
|
|
4
|
+
// protoc v3.21.12
|
|
5
|
+
// source: auth.proto
|
|
6
|
+
|
|
7
|
+
/* eslint-disable */
|
|
8
|
+
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
|
|
9
|
+
import { Observable } from "rxjs";
|
|
10
|
+
|
|
11
|
+
export const protobufPackage = "auth.v1";
|
|
12
|
+
|
|
13
|
+
/** указываем версию протобуфера */
|
|
14
|
+
|
|
15
|
+
export interface SendOtpRequest {
|
|
16
|
+
/** менять номер нельзя, чтоб не было рассинхронизации данных */
|
|
17
|
+
identifier: string;
|
|
18
|
+
type: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SendOtpResponse {
|
|
22
|
+
ok: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const AUTH_V1_PACKAGE_NAME = "auth.v1";
|
|
26
|
+
|
|
27
|
+
export interface AuthServiceClient {
|
|
28
|
+
sendOtp(request: SendOtpRequest): Observable<SendOtpResponse>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AuthServiceController {
|
|
32
|
+
sendOtp(request: SendOtpRequest): Promise<SendOtpResponse> | Observable<SendOtpResponse> | SendOtpResponse;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function AuthServiceControllerMethods() {
|
|
36
|
+
return function (constructor: Function) {
|
|
37
|
+
const grpcMethods: string[] = ["sendOtp"];
|
|
38
|
+
for (const method of grpcMethods) {
|
|
39
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
40
|
+
GrpcMethod("AuthService", method)(constructor.prototype[method], method, descriptor);
|
|
41
|
+
}
|
|
42
|
+
const grpcStreamMethods: string[] = [];
|
|
43
|
+
for (const method of grpcStreamMethods) {
|
|
44
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
45
|
+
GrpcStreamMethod("AuthService", method)(constructor.prototype[method], method, descriptor);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const AUTH_SERVICE_NAME = "AuthService";
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ticket_for_cinema/contracts",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Contracts for microservices",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"generate": "protoc -I ./proto ./proto/*.proto --ts_proto_out=./gen --ts_proto_opt=nestJs=true,package=omit"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"proto",
|
|
10
|
+
"gen"
|
|
11
|
+
],
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@nestjs/microservices": "^11.1.11",
|
|
14
|
+
"rxjs": "^7.8.2"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"ts-proto": "^1.176.0"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/proto/auth.proto
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
syntax = "proto3"; // указываем версию протобуфера
|
|
2
|
+
|
|
3
|
+
package auth.v1; // указываем пакет тут указываем доменную область
|
|
4
|
+
|
|
5
|
+
service AuthService {
|
|
6
|
+
rpc SendOtp (SendOtpRequest) returns (SendOtpResponse);
|
|
7
|
+
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
message SendOtpRequest {
|
|
11
|
+
string identifier = 1; // менять номер нельзя, чтоб не было рассинхронизации данных
|
|
12
|
+
string type = 2;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
message SendOtpResponse {
|
|
16
|
+
bool ok = 1;
|
|
17
|
+
}
|
package/proto/redme.md
ADDED
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
# Конспект по Protocol Buffers (proto файлам) для gRPC
|
|
2
|
+
|
|
3
|
+
## Что такое .proto файл?
|
|
4
|
+
|
|
5
|
+
`.proto` файл - это файл описания данных и сервисов для gRPC. Он определяет:
|
|
6
|
+
|
|
7
|
+
- **Структуру сообщений** (какие данные передаются)
|
|
8
|
+
- **Сервисы и методы** (какие операции можно выполнять)
|
|
9
|
+
- **Типы данных** (какие типы полей используются)
|
|
10
|
+
|
|
11
|
+
Из `.proto` файла генерируется код на разных языках программирования (TypeScript, Go, Python и т.д.)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Базовая структура .proto файла
|
|
16
|
+
|
|
17
|
+
```protobuf
|
|
18
|
+
syntax = "proto3"; // Версия Protocol Buffers (всегда используй proto3)
|
|
19
|
+
|
|
20
|
+
package auth.v1; // Пакет - организация кода (как namespace)
|
|
21
|
+
|
|
22
|
+
// Сообщение (структура данных)
|
|
23
|
+
message SendOtpRequest {
|
|
24
|
+
string identifier = 1; // Поле: тип название = номер
|
|
25
|
+
string type = 2;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Сервис (набор методов)
|
|
29
|
+
service AuthService {
|
|
30
|
+
rpc SendOtp(SendOtpRequest) returns (SendOtpResponse); // Метод
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 1. Синтаксис и пакет
|
|
37
|
+
|
|
38
|
+
### `syntax = "proto3"`
|
|
39
|
+
|
|
40
|
+
- Указывает версию Protocol Buffers
|
|
41
|
+
- Всегда используй `proto3` (самая новая версия)
|
|
42
|
+
|
|
43
|
+
### `package auth.v1`
|
|
44
|
+
|
|
45
|
+
- Организует код в пространство имен
|
|
46
|
+
- Помогает избежать конфликтов имен
|
|
47
|
+
- Формат: `название.версия` (например, `auth.v1`, `user.v2`)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 2. Сообщения (Messages)
|
|
52
|
+
|
|
53
|
+
Сообщения - это структуры данных (как классы или интерфейсы)
|
|
54
|
+
|
|
55
|
+
```protobuf
|
|
56
|
+
message User {
|
|
57
|
+
string name = 1; // Поле 1: имя пользователя
|
|
58
|
+
int32 age = 2; // Поле 2: возраст
|
|
59
|
+
bool is_active = 3; // Поле 3: активен ли
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Важно про номера полей:
|
|
64
|
+
|
|
65
|
+
- Каждое поле имеет **уникальный номер** (1, 2, 3...)
|
|
66
|
+
- Номера **нельзя менять** после релиза (иначе сломается совместимость)
|
|
67
|
+
- Номера 1-15 занимают 1 байт (используй для частых полей)
|
|
68
|
+
- Номера 16-2047 занимают 2 байта
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 3. Типы данных
|
|
73
|
+
|
|
74
|
+
### Скалярные типы (простые):
|
|
75
|
+
|
|
76
|
+
| Proto тип | Описание | Пример |
|
|
77
|
+
| --------- | --------------------------------- | ---------------- |
|
|
78
|
+
| `string` | Строка | `"Привет"` |
|
|
79
|
+
| `int32` | Целое число 32-бит | `42` |
|
|
80
|
+
| `int64` | Целое число 64-бит | `1234567890` |
|
|
81
|
+
| `uint32` | Беззнаковое целое 32-бит | `100` |
|
|
82
|
+
| `uint64` | Беззнаковое целое 64-бит | `9999` |
|
|
83
|
+
| `bool` | Булево значение | `true` / `false` |
|
|
84
|
+
| `float` | Число с плавающей точкой | `3.14` |
|
|
85
|
+
| `double` | Число с плавающей точкой (точнее) | `3.14159265` |
|
|
86
|
+
| `bytes` | Бинарные данные | `[0x01, 0x02]` |
|
|
87
|
+
|
|
88
|
+
### Пример:
|
|
89
|
+
|
|
90
|
+
```protobuf
|
|
91
|
+
message Product {
|
|
92
|
+
string name = 1; // "iPhone"
|
|
93
|
+
double price = 2; // 999.99
|
|
94
|
+
int32 quantity = 3; // 10
|
|
95
|
+
bool in_stock = 4; // true
|
|
96
|
+
bytes image = 5; // бинарные данные картинки
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 4. Повторяющиеся поля (массивы)
|
|
103
|
+
|
|
104
|
+
Используй `repeated` для массивов:
|
|
105
|
+
|
|
106
|
+
```protobuf
|
|
107
|
+
message ShoppingCart {
|
|
108
|
+
repeated string items = 1; // Массив строк: ["яблоко", "банан"]
|
|
109
|
+
repeated int32 quantities = 2; // Массив чисел: [5, 3]
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 5. Вложенные сообщения
|
|
116
|
+
|
|
117
|
+
Можно использовать одно сообщение внутри другого:
|
|
118
|
+
|
|
119
|
+
```protobuf
|
|
120
|
+
message Address {
|
|
121
|
+
string city = 1;
|
|
122
|
+
string street = 2;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
message User {
|
|
126
|
+
string name = 1;
|
|
127
|
+
Address address = 2; // Вложенное сообщение
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 6. Enum (перечисления)
|
|
134
|
+
|
|
135
|
+
Для фиксированного набора значений:
|
|
136
|
+
|
|
137
|
+
```protobuf
|
|
138
|
+
enum Status {
|
|
139
|
+
STATUS_UNSPECIFIED = 0; // Всегда начинай с 0 и _UNSPECIFIED
|
|
140
|
+
STATUS_PENDING = 1;
|
|
141
|
+
STATUS_APPROVED = 2;
|
|
142
|
+
STATUS_REJECTED = 3;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
message Order {
|
|
146
|
+
string id = 1;
|
|
147
|
+
Status status = 2; // Использование enum
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Важно:** Первое значение enum всегда должно быть `0` и называться `НАЗВАНИЕ_UNSPECIFIED`
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 7. Опциональные поля
|
|
156
|
+
|
|
157
|
+
В proto3 все поля опциональны по умолчанию. Если поле не задано, оно имеет значение по умолчанию:
|
|
158
|
+
|
|
159
|
+
- `string` → `""`
|
|
160
|
+
- `int32` → `0`
|
|
161
|
+
- `bool` → `false`
|
|
162
|
+
|
|
163
|
+
Если нужно явно указать, что поле опционально:
|
|
164
|
+
|
|
165
|
+
```protobuf
|
|
166
|
+
message User {
|
|
167
|
+
string name = 1;
|
|
168
|
+
optional string nickname = 2; // Может быть null
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 8. Сервисы (Services)
|
|
175
|
+
|
|
176
|
+
Сервис - это набор RPC методов (удаленных вызовов)
|
|
177
|
+
|
|
178
|
+
```protobuf
|
|
179
|
+
service UserService {
|
|
180
|
+
// Простой вызов: один запрос → один ответ
|
|
181
|
+
rpc GetUser(GetUserRequest) returns (GetUserResponse);
|
|
182
|
+
|
|
183
|
+
// Server streaming: один запрос → много ответов
|
|
184
|
+
rpc ListUsers(ListUsersRequest) returns (stream User);
|
|
185
|
+
|
|
186
|
+
// Client streaming: много запросов → один ответ
|
|
187
|
+
rpc CreateUsers(stream CreateUserRequest) returns (CreateUsersResponse);
|
|
188
|
+
|
|
189
|
+
// Bidirectional streaming: много запросов ↔ много ответов
|
|
190
|
+
rpc Chat(stream ChatMessage) returns (stream ChatMessage);
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Типы методов:
|
|
195
|
+
|
|
196
|
+
1. **Unary (обычный)** - один запрос, один ответ
|
|
197
|
+
|
|
198
|
+
```protobuf
|
|
199
|
+
rpc SendOtp(SendOtpRequest) returns (SendOtpResponse);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
2. **Server streaming** - один запрос, много ответов (стрим)
|
|
203
|
+
|
|
204
|
+
```protobuf
|
|
205
|
+
rpc WatchOrders(WatchRequest) returns (stream Order);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
3. **Client streaming** - много запросов (стрим), один ответ
|
|
209
|
+
|
|
210
|
+
```protobuf
|
|
211
|
+
rpc UploadFile(stream FileChunk) returns (UploadResponse);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
4. **Bidirectional streaming** - стрим в обе стороны
|
|
215
|
+
```protobuf
|
|
216
|
+
rpc Chat(stream Message) returns (stream Message);
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## 9. Импорты
|
|
222
|
+
|
|
223
|
+
Можно импортировать другие .proto файлы:
|
|
224
|
+
|
|
225
|
+
```protobuf
|
|
226
|
+
import "google/protobuf/timestamp.proto";
|
|
227
|
+
import "common/types.proto";
|
|
228
|
+
|
|
229
|
+
message Post {
|
|
230
|
+
string title = 1;
|
|
231
|
+
google.protobuf.Timestamp created_at = 2; // Использование импортированного типа
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 10. Комментарии
|
|
238
|
+
|
|
239
|
+
```protobuf
|
|
240
|
+
// Однострочный комментарий
|
|
241
|
+
|
|
242
|
+
/*
|
|
243
|
+
Многострочный
|
|
244
|
+
комментарий
|
|
245
|
+
*/
|
|
246
|
+
|
|
247
|
+
message User {
|
|
248
|
+
string name = 1; // Комментарий к полю
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 11. Полный пример .proto файла
|
|
255
|
+
|
|
256
|
+
```protobuf
|
|
257
|
+
syntax = "proto3";
|
|
258
|
+
|
|
259
|
+
package shop.v1;
|
|
260
|
+
|
|
261
|
+
import "google/protobuf/timestamp.proto";
|
|
262
|
+
import "google/protobuf/duration.proto";
|
|
263
|
+
import "google/protobuf/struct.proto";
|
|
264
|
+
import "google/protobuf/empty.proto";
|
|
265
|
+
import "google/protobuf/any.proto";
|
|
266
|
+
|
|
267
|
+
// Перечисление статусов заказа
|
|
268
|
+
enum OrderStatus {
|
|
269
|
+
ORDER_STATUS_UNSPECIFIED = 0;
|
|
270
|
+
ORDER_STATUS_PENDING = 1;
|
|
271
|
+
ORDER_STATUS_PAID = 2;
|
|
272
|
+
ORDER_STATUS_SHIPPED = 3;
|
|
273
|
+
ORDER_STATUS_DELIVERED = 4;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Сообщение: товар
|
|
277
|
+
message Product {
|
|
278
|
+
string id = 1;
|
|
279
|
+
string name = 2;
|
|
280
|
+
double price = 3;
|
|
281
|
+
int32 stock = 4;
|
|
282
|
+
google.protobuf.Timestamp created_at = 5; // время создания, но перед этим импортировать google.protobuf.Timestamp
|
|
283
|
+
google.protobuf.Duration duration = 6; // длительность, но перед этим импортировать google.protobuf.Duration
|
|
284
|
+
google.protobuf.Struct metadata = 7; // метаданные (структура json внутри протобуфера), но перед этим импортировать google.protobuf.Struct
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Сообщение: заказ
|
|
288
|
+
message Order {
|
|
289
|
+
string id = 1;
|
|
290
|
+
string user_id = 2;
|
|
291
|
+
repeated Product products = 3; // Массив товаров
|
|
292
|
+
OrderStatus status = 4; // Статус из enum
|
|
293
|
+
double total_price = 5;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Запрос на создание заказа
|
|
297
|
+
message CreateOrderRequest {
|
|
298
|
+
string user_id = 1;
|
|
299
|
+
repeated string product_ids = 2;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Ответ на создание заказа
|
|
303
|
+
message CreateOrderResponse {
|
|
304
|
+
Order order = 1;
|
|
305
|
+
bool success = 2;
|
|
306
|
+
string message = 3;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Сервис для работы с заказами
|
|
310
|
+
service OrderService {
|
|
311
|
+
// Создать заказ
|
|
312
|
+
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
|
|
313
|
+
|
|
314
|
+
// Получить заказ по ID
|
|
315
|
+
rpc GetOrder(GetOrderRequest) returns (Order);
|
|
316
|
+
|
|
317
|
+
// Получить список всех заказов (стрим)
|
|
318
|
+
rpc ListOrders(ListOrdersRequest) returns (stream Order);
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## 12. Лучшие практики
|
|
325
|
+
|
|
326
|
+
### ✅ Делай так:
|
|
327
|
+
|
|
328
|
+
- Всегда используй `syntax = "proto3"`
|
|
329
|
+
- Называй пакеты в формате `название.v1`, `название.v2`
|
|
330
|
+
- Первое значение enum всегда `0` и `_UNSPECIFIED`
|
|
331
|
+
- Используй `snake_case` для полей: `user_name`, `created_at`
|
|
332
|
+
- Используй `PascalCase` для сообщений: `UserProfile`, `CreateOrderRequest`
|
|
333
|
+
- Добавляй комментарии к сложным полям
|
|
334
|
+
|
|
335
|
+
### ❌ Не делай так:
|
|
336
|
+
|
|
337
|
+
- Не меняй номера полей после релиза
|
|
338
|
+
- Не удаляй поля (помечай как `reserved` если нужно)
|
|
339
|
+
- Не используй `required` (в proto3 его нет)
|
|
340
|
+
- Не используй одинаковые номера для разных полей
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## 13. Зарезервированные поля
|
|
345
|
+
|
|
346
|
+
Если нужно удалить поле, но сохранить его номер:
|
|
347
|
+
|
|
348
|
+
```protobuf
|
|
349
|
+
message User {
|
|
350
|
+
reserved 2, 5 to 10; // Зарезервированные номера
|
|
351
|
+
reserved "old_field", "deleted"; // Зарезервированные имена
|
|
352
|
+
|
|
353
|
+
string name = 1;
|
|
354
|
+
int32 age = 3;
|
|
355
|
+
// Поле 2 удалено, но номер зарезервирован
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## 14. Как использовать .proto файлы
|
|
362
|
+
|
|
363
|
+
1. **Создай .proto файл** с описанием данных и сервисов
|
|
364
|
+
2. **Сгенерируй код** с помощью компилятора `protoc`:
|
|
365
|
+
```bash
|
|
366
|
+
protoc --go_out=. --go-grpc_out=. auth.proto
|
|
367
|
+
```
|
|
368
|
+
3. **Используй сгенерированный код** в своем приложении
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Резюме
|
|
373
|
+
|
|
374
|
+
- `.proto` файл описывает структуру данных и API для gRPC
|
|
375
|
+
- **Messages** - структуры данных (как классы)
|
|
376
|
+
- **Services** - наборы методов (API)
|
|
377
|
+
- **Типы данных**: `string`, `int32`, `bool`, `repeated` и др.
|
|
378
|
+
- **Enum** - перечисления фиксированных значений
|
|
379
|
+
- **Номера полей** - уникальные и неизменяемые
|
|
380
|
+
- **4 типа RPC**: unary, server streaming, client streaming, bidirectional
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## 15. Команда генерации TypeScript кода
|
|
385
|
+
|
|
386
|
+
### Команда:
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
protoc -I ./proto ./proto/*.proto --ts_proto_out=./gen --ts_proto_opt=nestJs=true,package=omit
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Разбор команды по частям:
|
|
393
|
+
|
|
394
|
+
| Параметр | Описание | Пример |
|
|
395
|
+
| ---------------------- | ---------------------------------- | --------------------------------- |
|
|
396
|
+
| `protoc` | Компилятор Protocol Buffers | Основная программа |
|
|
397
|
+
| `-I ./proto` | Папка с .proto файлами (include) | Ищет файлы в папке `./proto` |
|
|
398
|
+
| `./proto/*.proto` | Все .proto файлы для обработки | `auth.proto`, `user.proto` и т.д. |
|
|
399
|
+
| `--ts_proto_out=./gen` | Выходная папка для TypeScript кода | Генерирует файлы в папке `./gen` |
|
|
400
|
+
| `--ts_proto_opt=...` | Опции генерации | Настройки формата кода |
|
|
401
|
+
|
|
402
|
+
### Опции генерации:
|
|
403
|
+
|
|
404
|
+
| Опция | Что делает | Пример |
|
|
405
|
+
| -------------- | ----------------------------------- | -------------------------------------------------- |
|
|
406
|
+
| `nestJs=true` | Генерирует код совместимый с NestJS | Декораторы `@GrpcMethod()` |
|
|
407
|
+
| `package=omit` | Пропускает префикс пакета в именах | Вместо `auth.v1.SendOtpRequest` → `SendOtpRequest` |
|
|
408
|
+
|
|
409
|
+
### Что генерируется:
|
|
410
|
+
|
|
411
|
+
Из файла `auth.proto`:
|
|
412
|
+
|
|
413
|
+
```protobuf
|
|
414
|
+
service AuthService {
|
|
415
|
+
rpc SendOtp (SendOtpRequest) returns (SendOtpResponse);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
message SendOtpRequest {
|
|
419
|
+
string identifier = 1;
|
|
420
|
+
string type = 2;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
message SendOtpResponse {
|
|
424
|
+
bool ok = 1;
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
Генерируется `gen/auth.ts`:
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
// Интерфейсы для сообщений
|
|
432
|
+
export interface SendOtpRequest {
|
|
433
|
+
identifier: string;
|
|
434
|
+
type: string;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
export interface SendOtpResponse {
|
|
438
|
+
ok: boolean;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Клиент и контроллер для NestJS
|
|
442
|
+
export interface AuthServiceClient {
|
|
443
|
+
sendOtp(request: SendOtpRequest): Observable<SendOtpResponse>;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
export interface AuthServiceController {
|
|
447
|
+
sendOtp(
|
|
448
|
+
request: SendOtpRequest
|
|
449
|
+
): Promise<SendOtpResponse> | Observable<SendOtpResponse> | SendOtpResponse;
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Пример использования в NestJS:
|
|
454
|
+
|
|
455
|
+
**Контроллер:**
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
@Controller()
|
|
459
|
+
export class AuthController implements AuthServiceController {
|
|
460
|
+
@GrpcMethod("SendOtp")
|
|
461
|
+
async sendOtp(request: SendOtpRequest): Promise<SendOtpResponse> {
|
|
462
|
+
return { ok: true };
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**Клиент:**
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
@Injectable()
|
|
471
|
+
export class AuthClient {
|
|
472
|
+
constructor(@Inject("AUTH_SERVICE") private client: ClientGrpc) {}
|
|
473
|
+
|
|
474
|
+
sendOtp(request: SendOtpRequest): Observable<SendOtpResponse> {
|
|
475
|
+
return this.client
|
|
476
|
+
.getService<AuthServiceClient>("AuthService")
|
|
477
|
+
.sendOtp(request);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## 16. Установка необходимых инструментов
|
|
485
|
+
|
|
486
|
+
### 1. Protocol Buffers компилятор:
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
# Установить protoc (добавить в PATH)
|
|
490
|
+
# Скачать с: https://github.com/protocolbuffers/protobuf/releases
|
|
491
|
+
# Или через пакетный менеджер
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### 2. TypeScript плагин:
|
|
495
|
+
|
|
496
|
+
```bash
|
|
497
|
+
npm install -g ts-proto
|
|
498
|
+
# или локально
|
|
499
|
+
npm install -D ts-proto
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### 3. Проверка установки:
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
protoc --version # Проверка protoc
|
|
506
|
+
protoc-gen-ts_proto --version # Проверка плагина
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## 17. Полный процесс работы с .proto файлами
|
|
512
|
+
|
|
513
|
+
1. **Создать .proto файл** с описанием сервисов и сообщений
|
|
514
|
+
2. **Установить инструменты** (`protoc` и `ts-proto`)
|
|
515
|
+
3. **Сгенерировать TypeScript код** с помощью команды
|
|
516
|
+
4. **Использовать сгенерированные интерфейсы** в NestJS приложении
|
|
517
|
+
5. **Реализовать контроллеры** и клиенты на основе сгенерированного кода
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
Это основа для работы с gRPC! 🚀
|