Skip to main content

fraiseql_server/routes/api/
openapi.rs

1//! `OpenAPI` specification for FraiseQL REST APIs.
2//!
3//! Provides a static `OpenAPI` 3.0.0 specification documenting all API endpoints,
4//! request/response schemas, and authentication requirements.
5
6/// Get complete `OpenAPI` 3.0.0 specification as JSON string.
7#[must_use]
8pub fn get_openapi_spec() -> String {
9    serde_json::json!({
10        "openapi": "3.0.0",
11        "info": {
12            "title": "FraiseQL Agent APIs",
13            "description": "GraphQL query intelligence, federation discovery, and administration APIs for FraiseQL",
14            "version": "1.0.0",
15            "contact": {
16                "name": "FraiseQL Support",
17                "url": "https://github.com/fraiseql/fraiseql"
18            },
19            "license": {
20                "name": "MIT OR Apache-2.0"
21            }
22        },
23        "servers": [
24            {
25                "url": "http://localhost:8080",
26                "description": "Local development server"
27            },
28            {
29                "url": "https://api.fraiseql.example.com",
30                "description": "Production server"
31            }
32        ],
33        "paths": {
34            "/api/v1/query/explain": {
35                "post": {
36                    "summary": "Analyze GraphQL query complexity",
37                    "description": "Analyzes a GraphQL query for depth, field count, and estimated execution cost. Returns complexity metrics and optimization recommendations.",
38                    "tags": ["Query Intelligence"],
39                    "requestBody": {
40                        "required": true,
41                        "content": {
42                            "application/json": {
43                                "schema": {
44                                    "$ref": "#/components/schemas/ExplainRequest"
45                                }
46                            }
47                        }
48                    },
49                    "responses": {
50                        "200": {
51                            "description": "Query analysis successful",
52                            "content": {
53                                "application/json": {
54                                    "schema": {
55                                        "$ref": "#/components/schemas/ApiResponseExplain"
56                                    }
57                                }
58                            }
59                        },
60                        "400": {
61                            "description": "Invalid query or validation error"
62                        }
63                    }
64                }
65            },
66            "/api/v1/query/validate": {
67                "post": {
68                    "summary": "Validate GraphQL query syntax",
69                    "description": "Validates GraphQL query syntax without executing analysis. Fast validation for batch operations.",
70                    "tags": ["Query Intelligence"],
71                    "requestBody": {
72                        "required": true,
73                        "content": {
74                            "application/json": {
75                                "schema": {
76                                    "$ref": "#/components/schemas/ValidateRequest"
77                                }
78                            }
79                        }
80                    },
81                    "responses": {
82                        "200": {
83                            "description": "Query validation result",
84                            "content": {
85                                "application/json": {
86                                    "schema": {
87                                        "$ref": "#/components/schemas/ApiResponseValidate"
88                                    }
89                                }
90                            }
91                        }
92                    }
93                }
94            },
95            "/api/v1/query/stats": {
96                "get": {
97                    "summary": "Get query performance statistics",
98                    "description": "Retrieves historical performance metrics for queries. Requires metrics collection to be enabled.",
99                    "tags": ["Query Intelligence"],
100                    "responses": {
101                        "200": {
102                            "description": "Query statistics",
103                            "content": {
104                                "application/json": {
105                                    "schema": {
106                                        "$ref": "#/components/schemas/ApiResponseStats"
107                                    }
108                                }
109                            }
110                        }
111                    }
112                }
113            },
114            "/api/v1/federation/subgraphs": {
115                "get": {
116                    "summary": "List federation subgraphs",
117                    "description": "Returns all federated subgraphs with their URLs, managed entities, and health status.",
118                    "tags": ["Federation"],
119                    "responses": {
120                        "200": {
121                            "description": "List of subgraphs",
122                            "content": {
123                                "application/json": {
124                                    "schema": {
125                                        "$ref": "#/components/schemas/ApiResponseSubgraphs"
126                                    }
127                                }
128                            }
129                        }
130                    }
131                }
132            },
133            "/api/v1/federation/graph": {
134                "get": {
135                    "summary": "Export federation dependency graph",
136                    "description": "Exports the federation structure showing subgraph relationships and entity resolution paths. Supports multiple output formats.",
137                    "tags": ["Federation"],
138                    "parameters": [
139                        {
140                            "name": "format",
141                            "in": "query",
142                            "description": "Output format: json (default), dot (Graphviz), or mermaid",
143                            "schema": {
144                                "type": "string",
145                                "enum": ["json", "dot", "mermaid"],
146                                "default": "json"
147                            }
148                        }
149                    ],
150                    "responses": {
151                        "200": {
152                            "description": "Federation graph in requested format",
153                            "content": {
154                                "application/json": {
155                                    "schema": {
156                                        "$ref": "#/components/schemas/ApiResponseGraph"
157                                    }
158                                }
159                            }
160                        },
161                        "400": {
162                            "description": "Invalid format parameter"
163                        }
164                    }
165                }
166            },
167            "/api/v1/schema.graphql": {
168                "get": {
169                    "summary": "Export schema as GraphQL SDL",
170                    "description": "Exports the compiled schema in GraphQL Schema Definition Language (SDL) format. Returns text/plain response.",
171                    "tags": ["Schema"],
172                    "responses": {
173                        "200": {
174                            "description": "Schema in SDL format",
175                            "content": {
176                                "text/plain": {
177                                    "schema": {
178                                        "type": "string",
179                                        "example": "type Query { users: [User!]! }\ntype User { id: ID! name: String! }"
180                                    }
181                                }
182                            }
183                        }
184                    }
185                }
186            },
187            "/api/v1/schema.json": {
188                "get": {
189                    "summary": "Export schema as JSON",
190                    "description": "Exports the full compiled schema in JSON format with type information and metadata.",
191                    "tags": ["Schema"],
192                    "responses": {
193                        "200": {
194                            "description": "Schema as JSON",
195                            "content": {
196                                "application/json": {
197                                    "schema": {
198                                        "$ref": "#/components/schemas/ApiResponseSchemaJson"
199                                    }
200                                }
201                            }
202                        }
203                    }
204                }
205            },
206            "/api/v1/admin/reload-schema": {
207                "post": {
208                    "summary": "Hot reload schema",
209                    "description": "Reload schema from file without restarting the server. Supports validation-only mode.",
210                    "tags": ["Admin"],
211                    "security": [
212                        {
213                            "BearerAuth": []
214                        }
215                    ],
216                    "requestBody": {
217                        "required": true,
218                        "content": {
219                            "application/json": {
220                                "schema": {
221                                    "$ref": "#/components/schemas/ReloadSchemaRequest"
222                                }
223                            }
224                        }
225                    },
226                    "responses": {
227                        "200": {
228                            "description": "Schema reload result",
229                            "content": {
230                                "application/json": {
231                                    "schema": {
232                                        "$ref": "#/components/schemas/ApiResponseReloadSchema"
233                                    }
234                                }
235                            }
236                        },
237                        "401": {
238                            "description": "Unauthorized - admin token required"
239                        },
240                        "400": {
241                            "description": "Invalid schema or validation error"
242                        }
243                    }
244                }
245            },
246            "/api/v1/admin/cache/clear": {
247                "post": {
248                    "summary": "Clear cache entries",
249                    "description": "Invalidate cache by scope: all (clear everything), entity (by type), or pattern (by glob).",
250                    "tags": ["Admin"],
251                    "security": [
252                        {
253                            "BearerAuth": []
254                        }
255                    ],
256                    "requestBody": {
257                        "required": true,
258                        "content": {
259                            "application/json": {
260                                "schema": {
261                                    "$ref": "#/components/schemas/CacheClearRequest"
262                                }
263                            }
264                        }
265                    },
266                    "responses": {
267                        "200": {
268                            "description": "Cache clear result",
269                            "content": {
270                                "application/json": {
271                                    "schema": {
272                                        "$ref": "#/components/schemas/ApiResponseCacheClear"
273                                    }
274                                }
275                            }
276                        },
277                        "401": {
278                            "description": "Unauthorized - admin token required"
279                        }
280                    }
281                }
282            },
283            "/api/v1/admin/config": {
284                "get": {
285                    "summary": "Get runtime configuration",
286                    "description": "Returns sanitized runtime configuration (secrets excluded). Requires admin token.",
287                    "tags": ["Admin"],
288                    "security": [
289                        {
290                            "BearerAuth": []
291                        }
292                    ],
293                    "responses": {
294                        "200": {
295                            "description": "Runtime configuration",
296                            "content": {
297                                "application/json": {
298                                    "schema": {
299                                        "$ref": "#/components/schemas/ApiResponseConfig"
300                                    }
301                                }
302                            }
303                        },
304                        "401": {
305                            "description": "Unauthorized - admin token required"
306                        }
307                    }
308                }
309            }
310        },
311        "components": {
312            "securitySchemes": {
313                "BearerAuth": {
314                    "type": "http",
315                    "scheme": "bearer",
316                    "description": "Bearer token for admin endpoints"
317                }
318            },
319            "schemas": {
320                "ExplainRequest": {
321                    "type": "object",
322                    "required": ["query"],
323                    "properties": {
324                        "query": {
325                            "type": "string",
326                            "description": "GraphQL query to analyze",
327                            "example": "query { users { id name } }"
328                        }
329                    }
330                },
331                "ComplexityInfo": {
332                    "type": "object",
333                    "properties": {
334                        "depth": {
335                            "type": "integer",
336                            "description": "Query nesting depth",
337                            "example": 2
338                        },
339                        "field_count": {
340                            "type": "integer",
341                            "description": "Total fields requested",
342                            "example": 10
343                        },
344                        "score": {
345                            "type": "integer",
346                            "description": "Complexity score (depth × field_count)",
347                            "example": 45
348                        }
349                    }
350                },
351                "ExplainResponse": {
352                    "type": "object",
353                    "properties": {
354                        "query": {
355                            "type": "string"
356                        },
357                        "sql": {
358                            "type": "string",
359                            "nullable": true,
360                            "description": "Generated SQL execution plan"
361                        },
362                        "estimated_cost": {
363                            "type": "integer"
364                        },
365                        "complexity": {
366                            "$ref": "#/components/schemas/ComplexityInfo"
367                        },
368                        "warnings": {
369                            "type": "array",
370                            "items": {
371                                "type": "string"
372                            }
373                        }
374                    }
375                },
376                "ValidateRequest": {
377                    "type": "object",
378                    "required": ["query"],
379                    "properties": {
380                        "query": {
381                            "type": "string",
382                            "description": "GraphQL query to validate"
383                        }
384                    }
385                },
386                "ValidateResponse": {
387                    "type": "object",
388                    "properties": {
389                        "valid": {
390                            "type": "boolean"
391                        },
392                        "errors": {
393                            "type": "array",
394                            "items": {
395                                "type": "string"
396                            }
397                        }
398                    }
399                },
400                "StatsResponse": {
401                    "type": "object",
402                    "properties": {
403                        "query_count": {
404                            "type": "integer"
405                        },
406                        "avg_latency_ms": {
407                            "type": "number"
408                        }
409                    }
410                },
411                "SubgraphInfo": {
412                    "type": "object",
413                    "properties": {
414                        "name": {
415                            "type": "string",
416                            "example": "users"
417                        },
418                        "url": {
419                            "type": "string",
420                            "example": "http://users.local/graphql"
421                        },
422                        "entities": {
423                            "type": "array",
424                            "items": {
425                                "type": "string"
426                            }
427                        },
428                        "healthy": {
429                            "type": "boolean"
430                        }
431                    }
432                },
433                "SubgraphsResponse": {
434                    "type": "object",
435                    "properties": {
436                        "subgraphs": {
437                            "type": "array",
438                            "items": {
439                                "$ref": "#/components/schemas/SubgraphInfo"
440                            }
441                        }
442                    }
443                },
444                "GraphResponse": {
445                    "type": "object",
446                    "properties": {
447                        "format": {
448                            "type": "string",
449                            "enum": ["json", "dot", "mermaid"]
450                        },
451                        "content": {
452                            "type": "string",
453                            "description": "Graph in requested format"
454                        }
455                    }
456                },
457                "JsonSchemaResponse": {
458                    "type": "object",
459                    "properties": {
460                        "schema": {
461                            "type": "object",
462                            "description": "Compiled schema as JSON"
463                        }
464                    }
465                },
466                "ReloadSchemaRequest": {
467                    "type": "object",
468                    "required": ["schema_path"],
469                    "properties": {
470                        "schema_path": {
471                            "type": "string",
472                            "description": "Path to compiled schema file",
473                            "example": "/path/to/schema.compiled.json"
474                        },
475                        "validate_only": {
476                            "type": "boolean",
477                            "description": "If true, only validate without applying",
478                            "default": false
479                        }
480                    }
481                },
482                "ReloadSchemaResponse": {
483                    "type": "object",
484                    "properties": {
485                        "success": {
486                            "type": "boolean"
487                        },
488                        "message": {
489                            "type": "string"
490                        }
491                    }
492                },
493                "CacheClearRequest": {
494                    "type": "object",
495                    "required": ["scope"],
496                    "properties": {
497                        "scope": {
498                            "type": "string",
499                            "enum": ["all", "entity", "pattern"],
500                            "description": "Scope for cache clearing"
501                        },
502                        "entity_type": {
503                            "type": "string",
504                            "nullable": true,
505                            "description": "Required if scope is 'entity'"
506                        },
507                        "pattern": {
508                            "type": "string",
509                            "nullable": true,
510                            "description": "Required if scope is 'pattern'"
511                        }
512                    }
513                },
514                "CacheClearResponse": {
515                    "type": "object",
516                    "properties": {
517                        "success": {
518                            "type": "boolean"
519                        },
520                        "entries_cleared": {
521                            "type": "integer"
522                        },
523                        "message": {
524                            "type": "string"
525                        }
526                    }
527                },
528                "AdminConfigResponse": {
529                    "type": "object",
530                    "properties": {
531                        "version": {
532                            "type": "string",
533                            "example": "2.0.0-a1"
534                        },
535                        "config": {
536                            "type": "object",
537                            "description": "Sanitized configuration (no secrets)",
538                            "additionalProperties": {
539                                "type": "string"
540                            }
541                        }
542                    }
543                },
544                "ApiResponse": {
545                    "type": "object",
546                    "properties": {
547                        "status": {
548                            "type": "string",
549                            "example": "success"
550                        },
551                        "data": {
552                            "type": "object"
553                        }
554                    }
555                },
556                "ApiResponseExplain": {
557                    "allOf": [
558                        {
559                            "$ref": "#/components/schemas/ApiResponse"
560                        },
561                        {
562                            "type": "object",
563                            "properties": {
564                                "data": {
565                                    "$ref": "#/components/schemas/ExplainResponse"
566                                }
567                            }
568                        }
569                    ]
570                },
571                "ApiResponseValidate": {
572                    "allOf": [
573                        {
574                            "$ref": "#/components/schemas/ApiResponse"
575                        },
576                        {
577                            "type": "object",
578                            "properties": {
579                                "data": {
580                                    "$ref": "#/components/schemas/ValidateResponse"
581                                }
582                            }
583                        }
584                    ]
585                },
586                "ApiResponseStats": {
587                    "allOf": [
588                        {
589                            "$ref": "#/components/schemas/ApiResponse"
590                        },
591                        {
592                            "type": "object",
593                            "properties": {
594                                "data": {
595                                    "$ref": "#/components/schemas/StatsResponse"
596                                }
597                            }
598                        }
599                    ]
600                },
601                "ApiResponseSubgraphs": {
602                    "allOf": [
603                        {
604                            "$ref": "#/components/schemas/ApiResponse"
605                        },
606                        {
607                            "type": "object",
608                            "properties": {
609                                "data": {
610                                    "$ref": "#/components/schemas/SubgraphsResponse"
611                                }
612                            }
613                        }
614                    ]
615                },
616                "ApiResponseGraph": {
617                    "allOf": [
618                        {
619                            "$ref": "#/components/schemas/ApiResponse"
620                        },
621                        {
622                            "type": "object",
623                            "properties": {
624                                "data": {
625                                    "$ref": "#/components/schemas/GraphResponse"
626                                }
627                            }
628                        }
629                    ]
630                },
631                "ApiResponseSchemaJson": {
632                    "allOf": [
633                        {
634                            "$ref": "#/components/schemas/ApiResponse"
635                        },
636                        {
637                            "type": "object",
638                            "properties": {
639                                "data": {
640                                    "$ref": "#/components/schemas/JsonSchemaResponse"
641                                }
642                            }
643                        }
644                    ]
645                },
646                "ApiResponseReloadSchema": {
647                    "allOf": [
648                        {
649                            "$ref": "#/components/schemas/ApiResponse"
650                        },
651                        {
652                            "type": "object",
653                            "properties": {
654                                "data": {
655                                    "$ref": "#/components/schemas/ReloadSchemaResponse"
656                                }
657                            }
658                        }
659                    ]
660                },
661                "ApiResponseCacheClear": {
662                    "allOf": [
663                        {
664                            "$ref": "#/components/schemas/ApiResponse"
665                        },
666                        {
667                            "type": "object",
668                            "properties": {
669                                "data": {
670                                    "$ref": "#/components/schemas/CacheClearResponse"
671                                }
672                            }
673                        }
674                    ]
675                },
676                "ApiResponseConfig": {
677                    "allOf": [
678                        {
679                            "$ref": "#/components/schemas/ApiResponse"
680                        },
681                        {
682                            "type": "object",
683                            "properties": {
684                                "data": {
685                                    "$ref": "#/components/schemas/AdminConfigResponse"
686                                }
687                            }
688                        }
689                    ]
690                }
691            }
692        }
693    }).to_string()
694}