1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
<?php
namespace MediaWiki\Rest\Handler;
use MediaWiki\Config\Config;
use MediaWiki\Config\ServiceOptions;
use MediaWiki\MainConfigNames;
use MediaWiki\Rest\Handler;
use MediaWiki\Rest\Module\Module;
/**
* Core REST API endpoint that outputs discovery information, including a
* list of registered modules.
* Inspired by Google's API directory, see https://developers.google.com/discovery/v1/reference.
*/
class DiscoveryHandler extends Handler {
/**
* @internal
*/
private const CONSTRUCTOR_OPTIONS = [
MainConfigNames::RightsUrl,
MainConfigNames::RightsText,
MainConfigNames::EmergencyContact,
MainConfigNames::Sitename,
MainConfigNames::Server,
];
private ServiceOptions $options;
public function __construct( Config $config ) {
$options = new ServiceOptions( self::CONSTRUCTOR_OPTIONS, $config );
$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
$this->options = $options;
}
public function execute() {
// NOTE: must match docs/rest/discovery-1.0.json
return [
'mw-discovery' => '1.0',
'$schema' => 'https://www.mediawiki.org/schema/discovery-1.0',
'info' => $this->getInfoSpec(),
'servers' => $this->getServerList(),
'modules' => $this->getModuleMap(),
// TODO: link to aggregated spec
// TODO: list of component schemas
];
}
private function getModuleMap(): array {
$modules = [];
foreach ( $this->getRouter()->getModuleIds() as $moduleName ) {
$module = $this->getRouter()->getModule( $moduleName );
if ( $module ) {
$modules[$moduleName] = $this->getModuleSpec( $moduleName, $module );
}
}
return $modules;
}
private function getServerList(): array {
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#server-object
return [
[
'url' => $this->getRouter()->getRouteUrl( '' ),
]
];
}
private function getInfoSpec(): array {
return [
'title' => $this->options->get( MainConfigNames::Sitename ),
'mediawiki' => MW_VERSION,
'license' => $this->getLicenseSpec(),
'contact' => $this->getContactSpec(),
// TODO: terms of service
// TODO: owner/operator
// TODO: link to Special:RestSandbox
// TODO: link to https://www.mediawiki.org/wiki/API:REST_API
];
}
private function getLicenseSpec(): array {
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#license-object
// TODO: get terms-of-use URL, not content license.
return [
'name' => $this->options->get( MainConfigNames::RightsText ),
'url' => $this->options->get( MainConfigNames::RightsUrl ),
];
}
private function getContactSpec(): array {
// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#contact-object
return [
'email' => $this->options->get( MainConfigNames::EmergencyContact ),
];
}
private function getModuleSpec( string $moduleId, Module $module ): array {
return $module->getModuleDescription();
}
protected function getResponseBodySchemaFileName( string $method ): ?string {
return 'docs/rest/discovery-1.0.json';
}
}
|