MBL
Csharp / ЛР1: как показать работу на защите
Csharp вводный

ЛР1: как показать работу на защите

grpcitmodemopostmangrpcurl

Короткая шпаргалка на сам момент защиты — что запустить и что показать, без теории (она в ЛР1: UserService — gRPC, PostgreSQL и слоистая архитектура на троих).

Поднять окружение

docker compose up -d
dotnet build
dotnet run --project UserService

Сервис слушает localhost:5002. Reflection не подключён — grpcurl и Postman должны явно знать про UserService/Protos/user-service.proto.

Способ 1 — grpcurl (быстрее, без интерфейса)

Из папки UserService/:

grpcurl -plaintext -proto Protos/user-service.proto \
  -d '{"login":"user1","password":"pass1234","name":"Ivan","surname":"Petrov","age":25}' \
  localhost:5002 userService.UserService/CreateUser

Способ 2 — Postman

Postman умеет gRPC, но без reflection ему тоже нужен .proto руками:

  1. New → gRPC Request, адрес localhost:5002, Use plaintext включить (TLS не настроен).
  2. Вкладка Service definition → Import a .proto file → указать UserService/Protos/user-service.proto.
  3. В выпадающем списке методов появятся все 5 rpc — выбираешь метод, слева пишешь JSON тела запроса (как в примерах ниже), Invoke.

Сценарий показа — happy path по всем 5 методам

Прогнать по порядку, посмотреть результат каждого — этого достаточно, чтобы продемонстрировать всё ТЗ разом.

1. CreateUser — заводим первого пользователя:

{"login":"user1","password":"pass1234","name":"Ivan","surname":"Petrov","age":25}

Ответ: {"id":1,"login":"user1","name":"Ivan","surname":"Petrov","age":25} — обратить внимание, что password в ответе нет, это осознанное решение ([MapperIgnoreSource] в мапперe), а не забытое поле.

2. CreateUser — второй пользователь, id пригодится для DeleteUser ниже:

{"login":"user2","password":"pass5678","name":"Anna","surname":"Sidorova","age":30}

3. GetUserById — {"id":1} → возвращает user1 целиком.

4. GetUserByName — {"name":"Ivan","surname":"Petrov"} → {"users":[{...}]}, список, даже когда совпадение одно (по контракту — всегда массив, не одиночный объект).

5. UpdateUser — меняем всё, кроме id и login (login в запросе нет вообще):

{"id":1,"password":"newpass1","name":"Ivan","surname":"Ivanov","age":26}

Ответ содержит прежний login: "user1" — если спросят "а почему он не изменился" — потому что UpdateUser по ТЗ не имеет права его менять, и в .proto для этого метода поля login физически нет.

6. DeleteUser — {"id":2} → пустой ответ {}, значит удаление прошло.

Сценарий показа — три вида ошибок

Если время на защите позволяет, эти три вызова наглядно показывают, что валидация и обработка ошибок не только "для галочки":

Дубликат login (регистр другой специально — проверка регистронезависимости):

{"login":"USER1","password":"x","name":"Someone","surname":"Else","age":40}

→ Code: AlreadyExists, Message: User with login 'USER1' already exists.

Невалидный возраст:

{"login":"user3","password":"x","name":"A","surname":"B","age":150}

→ Code: InvalidArgument, Message: 'Age' must be between 1 and 120. You entered 150.

Несуществующий id (GetUserById с {"id":999}):

→ Code: NotFound, Message: User with id '999' was not found.

Если что-то пошло не так во время демо

  • Address already in use при dotnet run — старый процесс сервиса не остановился с прошлого раза: pkill -f UserService и запустить заново.
  • Правка в Database/*.sql не подхватилась — Postgres накатывает эти скрипты только при первом старте контейнера на пустом volume. docker compose down -v (обязательно с -v), затем docker compose up -d заново.
  • Нужны чистые данные перед показом (без мусора от прошлых прогонов) — не обязательно down -v, достаточно docker exec user-service-postgres psql -U user_service -d user_service -c "TRUNCATE TABLE users RESTART IDENTITY;".
Самопроверка 0 / 3
Поднимаю docker compose и сервис одной командой, без ручного экспорта PATH
Могу показать все 5 методов подряд с осмысленными данными, не гадая на ходу
Готов показать не только happy path, но и три вида ошибок: AlreadyExists, InvalidArgument, NotFound
Как усвоено?