[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-sovremennaya-razrabotka-web-kak-proektirovat-rest-api-v-spring-boot":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":21,"progress":22,"seo":23},1188,"kak-proektirovat-rest-api-v-spring-boot",37,"sovremennaya-razrabotka-web","Современная разработка WEB","🌐","Как проектировать REST API в Spring Boot?","Проектирование REST API в 2026 году строится по принципу API-first: сначала контракт (OpenAPI 3.1), потом реализация.\n\n### OpenAPI 3.1 спецификация\n\n\u003Cdetails>\n\u003Csummary>Пример OpenAPI-спецификации\u003C\u002Fsummary>\n\n```yaml\nopenapi: 3.1.0\ninfo:\n  title: Order Service API\n  version: 1.0.0\n\npaths:\n  \u002Forders:\n    post:\n      operationId: createOrder\n      summary: Создать новый заказ\n      tags: [Orders]\n      requestBody:\n        required: true\n        content:\n          application\u002Fjson:\n            schema:\n              $ref: '#\u002Fcomponents\u002Fschemas\u002FCreateOrderRequest'\n      responses:\n        '201':\n          description: Заказ создан\n          headers:\n            Location:\n              schema:\n                type: string\n                format: uri\n        '400':\n          $ref: '#\u002Fcomponents\u002Fresponses\u002FBadRequest'\n\n  \u002Forders\u002F{orderId}:\n    get:\n      operationId: getOrder\n      parameters:\n        - name: orderId\n          in: path\n          required: true\n          schema:\n            type: string\n            format: uuid\n      responses:\n        '200':\n          description: Успешный ответ\n        '404':\n          $ref: '#\u002Fcomponents\u002Fresponses\u002FNotFound'\n```\n\n\u003C\u002Fdetails>\n\n### Контроллер с версионированием API\n\nВерсионирование через URL-путь (\u002Fapi\u002Fv1\u002Forders) — наиболее простой и распространённый подход:\n\n```java\n@RestController\n@RequestMapping(\"\u002Fapi\u002Fv1\u002Forders\")\npublic class OrderController {\n\n    private final CreateOrderUseCase createOrderUseCase;\n    private final OrderDtoMapper mapper;\n\n    @PostMapping\n    public ResponseEntity\u003COrderResponse> createOrder(\n            @Valid @RequestBody CreateOrderRequest request) {\n        Order order = createOrderUseCase.create(mapper.toDomain(request));\n        URI location = URI.create(\"\u002Fapi\u002Fv1\u002Forders\u002F\" + order.getId());\n        return ResponseEntity.created(location).body(mapper.toResponse(order));\n    }\n\n    @GetMapping(\"\u002F{orderId}\")\n    public OrderResponse getOrder(@PathVariable UUID orderId) {\n        return mapper.toResponse(getOrderUseCase.getById(orderId));\n    }\n}\n```\n\n### Problem Detail (RFC 9457) для ошибок\n\nSpring Boot 3.x нативно поддерживает стандарт Problem Detail:\n\n\u003Cdetails>\n\u003Csummary>GlobalExceptionHandler\u003C\u002Fsummary>\n\n```java\n@RestControllerAdvice\npublic class GlobalExceptionHandler {\n\n    @ExceptionHandler(OrderNotFoundException.class)\n    public ProblemDetail handleOrderNotFound(OrderNotFoundException ex) {\n        ProblemDetail problem = ProblemDetail.forStatusAndDetail(\n            HttpStatus.NOT_FOUND, ex.getMessage());\n        problem.setTitle(\"Заказ не найден\");\n        problem.setType(URI.create(\"https:\u002F\u002Fapi.example.com\u002Ferrors\u002Forder-not-found\"));\n        problem.setProperty(\"orderId\", ex.getOrderId());\n        return problem;\n    }\n\n    @ExceptionHandler(MethodArgumentNotValidException.class)\n    public ProblemDetail handleValidation(MethodArgumentNotValidException ex) {\n        ProblemDetail problem = ProblemDetail.forStatusAndDetail(\n            HttpStatus.BAD_REQUEST, \"Ошибка валидации\");\n        Map\u003CString, String> errors = ex.getBindingResult().getFieldErrors().stream()\n            .collect(Collectors.toMap(\n                FieldError::getField,\n                fe -> fe.getDefaultMessage() != null ? fe.getDefaultMessage() : \"invalid\",\n                (a, b) -> a));\n        problem.setProperty(\"fieldErrors\", errors);\n        return problem;\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n### REST vs gRPC vs GraphQL\n\n| Критерий | REST | gRPC | GraphQL |\n|----------|------|------|---------|\n| Формат | JSON | Protobuf (бинарный) | JSON |\n| Контракт | OpenAPI 3.1 | .proto файлы | Schema |\n| Производительность | Средняя | Высокая | Средняя |\n| Подходит для | Public API, CRUD | Inter-service, высоконагруженные | Гибкие клиентские запросы |\n| Streaming | Нет (SSE\u002FWS) | Да (native) | Subscriptions |\n\n### Частые ошибки\n\n- Возврат доменных сущностей напрямую из API вместо DTO — утечка внутренней структуры\n- Отсутствие версионирования API — любое breaking change ломает клиентов\n- Использование HTTP 200 для всех ответов с кодом ошибки в теле — нарушение семантики HTTP\n- Отсутствие пагинации для коллекций\n\n> **На собеседовании:** интервьюер часто спрашивает про обработку ошибок в API. Упомяните Problem Detail (RFC 9457) и покажите, что знаете разницу между 400 (валидация) и 422 (бизнес-ошибка). Вопрос \"REST или gRPC?\" — ответ зависит от контекста: REST для public API, gRPC для inter-service.","","middle",[15,16,17,18,19,20],"rest-api","openapi","http","spring-boot","graphql","grpc",[],null,{"title":24,"description":25,"ogTitle":24,"ogDescription":26,"keywords":27,"schemaAnswer":38,"featuredSnippetReady":39},"Как проектировать REST API в Spring Boot — Gymterview","Проектирование REST API: API-first подход, OpenAPI 3.1, версионирование, Problem Detail (RFC 9457), сравнение REST vs gRPC vs GraphQL. Примеры на Spring Boot.","API-first подход, OpenAPI 3.1, Problem Detail для ошибок, версионирование и сравнение REST vs gRPC vs GraphQL.",[28,29,30,31,32,33,34,35,36,37],"REST API","Spring Boot","OpenAPI 3.1","API-first","Problem Detail","RFC 9457","версионирование API","gRPC","GraphQL","собеседование","Проектирование REST API строится по принципу API-first: сначала контракт (OpenAPI 3.1), потом реализация. Версионирование через URL-путь (\u002Fapi\u002Fv1\u002Forders). Ошибки обрабатываются через Problem Detail (RFC 9457) — Spring Boot 3.x поддерживает нативно. REST подходит для public API, gRPC для inter-service с высокой нагрузкой, GraphQL для гибких клиентских запросов.",true]