Little Navmap Web API Documentation - KOKAProduktion/littlenavmap GitHub Wiki

Structure

  • src

    • web
      • WebController: Instantiating and holding the WebApiController
      • RequestHandler: Passing API requests to the WebApiController
    • webapi
      • WebApiController: Resolving requests to dynamically invoked child classes of AbstractActionsController
      • ActionsControllerIndex: Available action controller classes registry
      • AbstractActionsController: Base class for invokable action controllers
        • AbstractLnmActionsController: Base class for LNM-specific action controllers
          • AirportActionsController: Airport actions controller implementation
          • MapActionsController: Map and map features actions controller implementation
          • SimActionsController: Active simulator/simconnect data actions controller implementation
          • UiActionsController: LNM UI related actions controller implementation
          • ...
      • WebApiRequest: Generic request object
      • WebApiResponse: Generic response object
    • common
      • AbstractInfoBuilder: Generic interface for LNM-specific views
        • JsonInfoBuilder: JSON info builder implementation, including nlohmann/json library via atools
        • ...
      • InfoBuilderTypes: Generic info builder parameter interfaces
  • web

    • webapi.yaml: OpenApi specification of the Little Navmap Web API

Concepts

Request Resolution

To avoid manual routing maintenance a naming convention pattern is used to resolve requests to controllers.

URL-Pattern: /<apibasepath>/<controller>/<action>

Example

/api/airport/info?ident=eddm
RequestHandler - /api 
    -> WebApiController - /airport/info 
        -> dynamically invokes matching 
           AirportActionsController::infoAction

Dynamic Controller Invocation

Using Qt's Meta-Object System allows to instance requested controllers and their actions by string. This removes the need for explicit action controller class definitions inside the agnostic WebApiController.

MVC

  • The LNM model is being exposed to action controllers via their AbstractLnmActionsController parent class.
    • All model interaction should be wrapped here.
    • Wrapping enables common usage by all derived action controllers.
  • The requested actions controller is resolving the requests params, calling the model and populating the info builder / view params via the generic AbstractInfoBuilder interface using defined InfoBuilderTypes as data transfer objects.
    • All model interaction calls and view params population should go here.
  • The info builder / view is mapping and formatting the provided data and returning the response body value.
    • All display/view-specific logic like formatting should go here.

Info Builders / Views

Utilizing the generic AbstractInfoBuilder and InfoBuilderTypes interfaces enables interchangeable info builders on the same action based for example on requested content MIME type. e.g. application/json => JsonInfoBuilder, application/xml => XmlInfoBuilder

How to

Add new API route/action

  1. Define a new operation at webapi.yaml (e.g. /aircraft/performance, operationId: aircraftPerformanceAction)
  2. Create or extend a controller deriving from AbstractLnmActionsController (e.g. AircraftActionsController)
  3. Add method (e.g. AircraftActionsController::performanceAction)
  4. Register a new controller at ActionsControllerIndex (qRegisterMetaType)
  5. Start LNM and test the route (e.g. webapi.yaml -> Swagger Editor)
  6. Implement away...

Compose an info builder response

  1. Define a new generic info builder parameter interface at InfoBuilderTypes
  2. Add desired response method at AbstractInfoBuilder and override it in its child builders (e.g. JsonInfoBuilder)
  3. Populate the new InfoBuilderType data inside the API actions controller
  4. Implement response method returning the response body
  5. Populate the web API response body by the info builders response method result

Test API routes/actions

  1. Copy/Paste webapi.yaml contents into the Swagger Editor
  2. Select desired action
  3. Click "Try Out"
  4. Provide required action parameters
  5. Click "Execute"
⚠️ **GitHub.com Fallback** ⚠️