Implementing REST Service Endpoints#
Service endpoints use FastAPI via the Omniverse microservices layer. All implementations use ServiceBase from
omni.flux.service.factory.
Extension Naming#
Service endpoints live in a .service extension (e.g. lightspeed.trex.my_feature.service). If one doesn’t exist for
the feature yet, scaffold it with the create-extension command first.
The canonical reference implementation is lightspeed.trex.asset_replacements.service — read it before implementing a
new service.
Service Class Template#
__all__ = ["MyFeatureService"]
from omni.flux.service.factory import ServiceBase
class MyFeatureService(ServiceBase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@classmethod
def prefix(cls) -> str:
return "/my-feature"
def router(self):
@self._router.get("/items", summary="Get all items")
async def get_items():
from my.core.extension import get_instance
return get_instance().get_items()
@self._router.post("/items", summary="Create an item")
async def create_item(body: MyItemModel):
omni.kit.commands.execute("CreateItemCommand", data=body)
return {"ok": True}
return self._router
Rules:
The service layer is thin — all business logic goes in
.core.Mutations must go through
omni.kit.commands.execute()so they are undoable.Use Pydantic models for request/response bodies.
prefix()must be unique across all registered services.
Factory Registration#
Register and unregister the service in the .service extension’s lifecycle:
from omni.flux.service.factory import get_instance as _get_service_factory_instance
from .service import MyFeatureService as _MyFeatureService
class MyServiceExtension(omni.ext.IExt):
def on_startup(self, _ext_id):
_get_service_factory_instance().register_plugins([_MyFeatureService])
def on_shutdown(self):
_get_service_factory_instance().unregister_plugins([_MyFeatureService])
Extension Dependencies#
[dependencies]
"omni.flux.service.factory" = {}
"omni.services.transport.server.base" = {}
Testing#
Service tests run against the live FastAPI router. Test at minimum:
Happy path: correct input returns the expected response and status code.
Validation: malformed or missing input returns 422.
Side effects: mutations call the expected command and the action is undoable.