Files
wanderer/lib/wanderer_app_web/open_api.ex
2025-07-16 20:39:30 +00:00

127 lines
3.9 KiB
Elixir

defmodule WandererAppWeb.OpenApi do
@moduledoc """
Generates OpenAPI spec for v1 JSON:API endpoints using AshJsonApi.
"""
alias OpenApiSpex.{OpenApi, Info, Server, Components}
def spec do
%OpenApi{
info: %Info{
title: "WandererApp v1 JSON:API",
version: "1.0.0",
description: """
JSON:API compliant endpoints for WandererApp.
## Features
- Filtering: Use `filter[attribute]=value` parameters
- Sorting: Use `sort=attribute` or `sort=-attribute` for descending
- Pagination: Use `page[limit]=n` and `page[offset]=n`
- Relationships: Include related resources with `include=relationship`
## Authentication
All endpoints require Bearer token authentication:
```
Authorization: Bearer YOUR_API_KEY
```
"""
},
servers: [
Server.from_endpoint(WandererAppWeb.Endpoint)
],
paths:
merge_custom_paths(AshJsonApi.OpenApi.paths([WandererApp.Api], [WandererApp.Api], %{})),
tags: AshJsonApi.OpenApi.tags([WandererApp.Api]),
components: %Components{
responses: AshJsonApi.OpenApi.responses(),
schemas: AshJsonApi.OpenApi.schemas([WandererApp.Api]),
securitySchemes: %{
"bearerAuth" => %{
"type" => "http",
"scheme" => "bearer",
"description" => "Map API key for authentication"
}
}
},
security: [%{"bearerAuth" => []}]
}
end
defp merge_custom_paths(ash_paths) do
custom_paths = %{
"/maps/{map_id}/systems_and_connections" => %{
"get" => %{
"tags" => ["maps"],
"summary" => "Get Map Systems and Connections",
"description" => "Retrieve both systems and connections for a map in a single response",
"operationId" => "getMapSystemsAndConnections",
"parameters" => [
%{
"name" => "map_id",
"in" => "path",
"description" => "Map ID",
"required" => true,
"schema" => %{"type" => "string"}
}
],
"responses" => %{
"200" => %{
"description" => "Combined systems and connections data",
"content" => %{
"application/json" => %{
"schema" => %{
"type" => "object",
"properties" => %{
"systems" => %{
"type" => "array",
"items" => %{
"$ref" => "#/components/schemas/MapSystem"
}
},
"connections" => %{
"type" => "array",
"items" => %{
"$ref" => "#/components/schemas/MapConnection"
}
}
}
}
}
}
},
"404" => %{
"description" => "Map not found",
"content" => %{
"application/json" => %{
"schema" => %{
"type" => "object",
"properties" => %{
"error" => %{"type" => "string"}
}
}
}
}
},
"401" => %{
"description" => "Unauthorized",
"content" => %{
"application/json" => %{
"schema" => %{
"type" => "object",
"properties" => %{
"error" => %{"type" => "string"}
}
}
}
}
}
},
"security" => [%{"bearerAuth" => []}]
}
}
}
Map.merge(ash_paths, custom_paths)
end
end