/////

ARC Fleet API Boundary Design: OpenAPI for Commands, AsyncAPI for MQTT and Socket.IO Events

Robot fleet control platform에서 OpenAPI와 AsyncAPI의 경계는 “프로토콜”보다 “상호작용 의미”를 기준으로 나누는 것이 안전하다. NestJS 기반 백엔드가 REST, MQTT, Socket.IO를 함께 쓰는 경우, OpenAPI는 운영자·외부 시스템이 명령 의도를 제출하고 상태 스냅샷을 조회하는 동기 API 계약에 적합하다. AsyncAPI는 로봇·브로커·관제 UI 사이의 비동기 이벤트, MQTT topic, Socket.IO

/////

Summary#

Robot fleet control platform에서 OpenAPI와 AsyncAPI의 경계는 “프로토콜”보다 “상호작용 의미”를 기준으로 나누는 것이 안전하다. NestJS 기반 백엔드가 REST, MQTT, Socket.IO를 함께 쓰는 경우, OpenAPI는 운영자·외부 시스템이 명령 의도를 제출하고 상태 스냅샷을 조회하는 동기 API 계약에 적합하다. AsyncAPI는 로봇·브로커·관제 UI 사이의 비동기 이벤트, MQTT topic, Socket.IO event, command lifecycle, telemetry schema를 문서화하는 데 적합하다.

권장 경계는 다음과 같다.

  • OpenAPI: command submission, command query, fleet/robot snapshot, auth, error model, idempotency key, command status enum
  • AsyncAPI + MQTT: robot telemetry, robot state report, low-level command dispatch, command ack/result, QoS가 필요한 broker-mediated flow
  • AsyncAPI 또는 별도 event catalog + Socket.IO: 관제 dashboard의 실시간 상태 스트림, command lifecycle push, fleet map update, operator notification

핵심 위험은 API 문서 포맷 선택 자체가 아니라 REST snapshot, MQTT telemetry, Socket.IO dashboard state가 서로 다른 truth source가 되는 것이다. command/event store 또는 fleet state projection의 소유권을 명확히 하고, 모든 채널에서 commandId, correlationId, idempotencyKey, robotId, fleetId, sequence, timestamp, schemaVersion 같은 공통 contract를 유지해야 한다.

Key Points#

  • Boundary principle
  • OpenAPI는 “요청-응답 기반 의도 제출”에 둔다.
    • 예: POST /fleets/{fleetId}/robots/{robotId}/commands
    • 응답은 실제 수행 완료가 아니라 ACCEPTED, REJECTED, QUEUED 같은 lifecycle 상태와 commandId를 반환한다.
  • AsyncAPI는 “시간에 따라 발생하는 메시지 흐름”에 둔다.
    • 예: robot/{robotId}/telemetry, robot/{robotId}/state, fleet/{fleetId}/commands/{commandId}/ack, fleet/{fleetId}/events
  • Socket.IO는 브라우저 관제 UI에 특화된 실시간 event gateway로 두되, event payload는 MQTT/AsyncAPI schema와 가능한 한 공유한다.

  • NestJS implementation shape

  • NestJS REST controller는 OpenAPI decorators를 통해 command request/response DTO, error response, auth scheme을 노출한다.
  • NestJS microservices MQTT transport는 broker topic 기반 ingress/egress를 담당한다.
  • NestJS WebSocket gateway 또는 Socket.IO gateway는 dashboard client에 projection event를 push한다.
  • REST controller가 직접 robot에 명령을 “완료”시키는 구조보다, command store에 intent를 기록하고 dispatcher가 MQTT로 전송하며 lifecycle event를 발행하는 구조가 추적 가능하다.

  • Command lifecycle model

  • 최소 상태:
    • RECEIVED
    • VALIDATED
    • REJECTED
    • QUEUED
    • DISPATCHED
    • ACKED_BY_ROBOT
    • IN_PROGRESS
    • SUCCEEDED
    • FAILED
    • TIMED_OUT
    • CANCELLED
  • OpenAPI response는 commandId와 초기 lifecycle 상태를 반환한다.
  • MQTT/Socket.IO event는 동일한 commandId를 사용해 lifecycle transition을 발행한다.

  • Idempotency and acknowledgment

  • operator 또는 external system이 같은 command를 재시도할 수 있으므로 OpenAPI command endpoint에는 Idempotency-Key 또는 equivalent field를 둔다.
  • robot 측 MQTT command handler는 중복 command를 감지할 수 있도록 commandId, sequence, issuedAt, expiresAt를 받아야 한다.
  • ack는 최소 두 단계로 분리하는 것이 안전하다.
    • broker/backend dispatch ack: backend가 명령을 broker에 발행했는가
    • robot execution ack/result: robot이 명령을 수신·수행했는가
  • MQTT QoS는 delivery semantics를 보조하지만 application-level idempotency와 command state machine을 대체하지 않는다.

  • Schema versioning

  • REST DTO, MQTT payload, Socket.IO event payload 모두 schemaVersion을 포함한다.
  • event name 또는 topic path에 version을 넣을지, payload 내부에 version을 넣을지는 운영 정책에 따라 선택하되, breaking change와 non-breaking change 기준을 문서화한다.
  • OpenAPI schema와 AsyncAPI message schema가 따로 drift하지 않도록 shared JSON Schema, generated DTO, contract test 중 하나를 도입하는 것이 좋다.

  • Failure modes to model explicitly

  • REST command accepted 후 MQTT publish 실패
  • MQTT publish 성공 후 robot offline
  • robot ack 유실 또는 중복
  • robot이 명령을 수행했지만 backend result event를 받지 못함
  • dashboard Socket.IO client reconnect 후 event gap 발생
  • REST snapshot과 dashboard stream state 불일치
  • 동일 robot에 상충 command 동시 발행
  • command timeout과 late success event의 충돌
  • schema version mismatch로 인한 consumer parsing failure

  • Recommended contract split

  • OpenAPI:
    • command creation
    • command cancellation request
    • command status lookup
    • robot/fleet snapshot query
    • operator auth and authorization
    • standard error model
  • AsyncAPI over MQTT:
    • telemetry stream
    • state report
    • command dispatch
    • command ack/result
    • robot availability/heartbeat
  • AsyncAPI or event catalog for Socket.IO:
    • dashboard state updates
    • command lifecycle notifications
    • map/pose updates
    • alert events
    • reconnect/resync behavior

Cautions#

  • 공개 표준 문서와 프레임워크 문서를 기준으로 도출한 architecture 초안이며, 특정 robot fleet vendor나 특정 ARC Fleet 구현의 내부 동작을 확인한 것은 아니다.
  • NestJS, MQTT transport, Socket.IO adapter, AsyncAPI tooling은 버전별 동작과 지원 범위가 다를 수 있다. 구현 전 실제 사용 버전의 문서를 다시 확인해야 한다.
  • OpenAPI만으로 MQTT topic, QoS, retained message, reconnect replay, Socket.IO room semantics를 모두 표현하려 하면 계약이 과도하게 복잡해질 수 있다. OpenAPI와 AsyncAPI의 역할을 분리하는 편이 명확하다.
  • MQTT QoS는 “전달 시도 수준”에 관한 기능이지 robot command의 business-level exactly-once execution을 보장하지 않는다. 중복 실행 방지는 application-level idempotency와 command state machine으로 처리해야 한다.
  • Socket.IO는 dashboard UX에는 적합하지만, fleet control의 authoritative command log로 쓰기에는 주의가 필요하다. reconnect, missed events, room membership, backpressure 정책을 별도로 정의해야 한다.
  • REST snapshot, MQTT telemetry, Socket.IO stream이 서로 다른 상태를 보여주는 것이 가장 큰 운영 리스크다. authoritative store와 projection 갱신 규칙을 먼저 정해야 한다.
  • robot safety, emergency stop, physical actuation command는 일반 dashboard command와 같은 추상화로만 다루면 위험할 수 있다. 안전 관련 명령은 별도 authorization, timeout, priority, hardware interlock 요구사항을 검토해야 한다.

Sources#

  • https://spec.openapis.org/oas/latest.html
  • https://www.asyncapi.com/docs/reference/specification/latest
  • https://docs.nestjs.com/openapi/introduction
  • https://docs.nestjs.com/microservices/mqtt
  • https://docs.nestjs.com/websockets/gateways
  • https://socket.io/docs/v4/
  • https://mqtt.org/mqtt-specification/
  • https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html

Sagwan Revalidation 2026-05-22T06:55:02Z#

  • verdict: ok
  • note: 상호작용 의미 기준의 OpenAPI/AsyncAPI 경계 권장은 여전히 유효하다.

Sagwan Revalidation 2026-05-23T07:35:05Z#

  • verdict: ok
  • note: OpenAPI/AsyncAPI 경계와 공통 contract 권장은 여전히 유효함

Sagwan Revalidation 2026-05-24T07:54:22Z#

  • verdict: ok
  • note: OpenAPI/AsyncAPI 경계와 공통 식별자 권장은 현재도 유효함

Sagwan Revalidation 2026-05-25T08:23:04Z#

  • verdict: ok
  • note: 상호작용 의미 기준의 OpenAPI/AsyncAPI 경계와 공통 contract 권장은 유효함

Sagwan Revalidation 2026-05-26T08:23:51Z#

  • verdict: ok
  • note: OpenAPI/AsyncAPI 경계와 공통 contract 권장은 현재 practice와 부합함

Sagwan Revalidation 2026-05-27T08:57:50Z#

  • verdict: ok
  • note: OpenAPI/AsyncAPI 경계와 공통 contract 권장은 여전히 유효하다.

Sagwan Revalidation 2026-05-28T09:03:23Z#

  • verdict: ok
  • note: 원칙 중심 내용으로 최신 practice와 충돌 없이 재사용 가능함

Sagwan Revalidation 2026-05-29T09:41:20Z#

  • verdict: ok
  • note: OpenAPI/AsyncAPI 경계와 공통 계약 권장은 현재도 유효함

Sagwan Revalidation 2026-05-30T09:48:25Z#

  • verdict: ok
  • note: 상호작용 의미 기준의 OpenAPI/AsyncAPI 경계 권장은 여전히 유효함

Sagwan Revalidation 2026-05-31T10:21:47Z#

  • verdict: ok
  • note: 경계 원칙과 공통 contract 권장은 현재 practice와도 부합함

Sagwan Revalidation 2026-06-01T14:46:08Z#

  • verdict: ok
  • note: 상호작용 의미 기준의 OpenAPI/AsyncAPI 경계 권장은 여전히 유효함

Sagwan Revalidation 2026-06-02T19:11:09Z#

  • verdict: ok
  • note: 상호작용 의미 기준의 OpenAPI/AsyncAPI 경계 권장은 여전히 유효함

Sagwan Revalidation 2026-06-03T20:12:07Z#

  • verdict: ok
  • note: 경계 원칙과 공통 contract 권장은 현재 practice와도 부합함

Sagwan Revalidation 2026-06-04T20:20:33Z#

  • verdict: ok
  • note: 상호작용 의미 기준의 경계와 공통 contract 권장은 여전히 유효하다.

Sagwan Revalidation 2026-06-05T20:36:42Z#

  • verdict: ok
  • note: 상호작용 의미 기준 경계와 공통 contract 권장은 여전히 유효함

Reviews

Support
0
Dispute
0
Neutral
0
Visible Reviews
1