Skip to content

Implement GET /apps/{app-id}/is-located-on endpoint #195

@bburda

Description

@bburda

Summary

Add a new discovery endpoint that returns the Component on which a given App runs. This is the reverse of the existing GET /components/{id}/hosts endpoint (which lists Apps hosted by a Component).


Proposed solution

GET /api/v1/apps/{app-id}/is-located-on

Returns the parent Component that hosts this App.

Path parameters:

Parameter Type Required Description
app-id string Yes App identifier (alphanumeric, underscores, hyphens, max 256 chars)

Request body: None

Response 200 OK:

{
  "items": [
    {
      "id": "engine_ecu",
      "name": "Engine ECU",
      "href": "/api/v1/components/engine_ecu"
    }
  ],
  "x-medkit": {
    "total_count": 1
  },
  "_links": {
    "self": "/api/v1/apps/{app-id}/is-located-on",
    "app": "/api/v1/apps/{app-id}"
  }
}

The items array will contain exactly 0 or 1 component — an App runs on at most one Component. If the App has no associated Component (e.g., standalone manifest-defined App), return an empty array.

Response 400 Bad Request:

Returned when the app-id format is invalid (empty, too long, contains illegal characters).

{
  "error_code": "invalid-parameter",
  "message": "Invalid app ID: contains illegal characters",
  "parameters": {
    "app_id": "bad id!"
  }
}

Response 404 Not Found:

Returned when no App with the given ID exists in any collection.

{
  "error_code": "entity-not-found",
  "message": "App not found",
  "parameters": {
    "app_id": "nonexistent_app"
  }
}

Additional context

Existing patterns to follow

  • Handler pattern: Use HandlerContext::validate_entity_id() for ID validation, then look up the App via DiscoveryManager::get_app(app_id). Follow the same structure as handle_app_depends_on in discovery_handlers.cpp.
  • Data source: The App struct already has a component_id field that holds the parent component ID. If non-empty, look up the Component to build the EntityReference.
  • Response envelope: Use the standard { "items": [...], "_links": {...} } format used by all other relationship endpoints.

Route registration

Register in rest_server.cpp::setup_routes():

srv->Get((api_path("/apps") + R"(/([^/]+)/is-located-on$)"), handler);

Place this before the generic GET /apps/{id} route to ensure correct matching.

Handler method

Add to DiscoveryHandlers:

void handle_app_is_located_on(const httplib::Request& req, httplib::Response& res);

Tests

  • Unit test: verify correct component returned for app with known component_id
  • Unit test: verify empty items array when app has no component
  • Unit test: 404 for nonexistent app
  • Unit test: 400 for invalid app ID format
  • Integration test: launch demo nodes, query the endpoint, verify response

Metadata

Metadata

Assignees

No one assigned

    Labels

    discoveryDiscovery endpoints or strategiesenhancementNew feature or requestgood first issueGood for newcomers

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions