Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better ApiDoc definitions #11433

Draft
wants to merge 25 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4511de9
missing urlParams for ChannelsController
notbakaneko Aug 12, 2024
87ded81
missing param types on BeatmapsController
notbakaneko Aug 12, 2024
115511b
missing params for BeatmapDiscussionPostsController
notbakaneko Aug 12, 2024
bd49f64
missing param types for BeatmapsetDiscussionVotesController
notbakaneko Aug 13, 2024
50527d0
missing param types for BeatmapDiscussionsController
notbakaneko Aug 13, 2024
1362cca
array on type not param
notbakaneko Aug 13, 2024
f05998d
missing param types for CommentsController
notbakaneko Aug 13, 2024
6da6049
missing required
notbakaneko Aug 13, 2024
143b6d5
correct link
notbakaneko Aug 13, 2024
9784473
missing param type on NotificationsController
notbakaneko Aug 13, 2024
937b0ad
missing params types on RankingsController
notbakaneko Aug 13, 2024
9bdd068
missing param types + fixes for UsersController
notbakaneko Aug 13, 2024
b02d4b4
setting example/no-example
notbakaneko Aug 13, 2024
7fe4e1f
use attribute for limit queryParam
notbakaneko Aug 14, 2024
45b854e
use attribute for page param
notbakaneko Aug 14, 2024
2e3eadd
combine strategy
notbakaneko Aug 14, 2024
bdf481b
offset attribute for query param doc
notbakaneko Aug 14, 2024
85aa097
attributes for sort query params in api doc
notbakaneko Aug 14, 2024
24db77a
wtf
notbakaneko Aug 15, 2024
aec383d
move id_asc and id_desc to own sort type
notbakaneko Aug 15, 2024
ed0aa52
all with_deleted should have no example (because it does nothing for …
notbakaneko Aug 15, 2024
77318fc
make the model default the default instead
notbakaneko Sep 11, 2024
f74e31a
correct syntax for array param
notbakaneko Sep 11, 2024
65ab5e4
wrong params
notbakaneko Sep 18, 2024
579027f
use the const
notbakaneko Sep 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions app/Docs/Attributes/Limit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Docs\Attributes;

use App\Models\Model;
use Attribute;
use Knuckles\Scribe\Attributes\GenericParam;

#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class Limit extends GenericParam
{
public function __construct(
int $default = Model::PER_PAGE,
int $minimum = 1,
int $maximum = 50,
string $description = 'Maximum number of results',
bool $required = false,
string|int $example = 'No-example',
) {
$description .= " (Default: {$default}, Minimum: {$minimum}, Maximum: {$maximum})";

parent::__construct('limit', 'integer', $description, $required, $example);
}
}
23 changes: 23 additions & 0 deletions app/Docs/Attributes/Offset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Docs\Attributes;

use Attribute;
use Knuckles\Scribe\Attributes\GenericParam;

#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class Offset extends GenericParam
{
public function __construct(
string $description = 'Result offset for pagination.',
bool $required = false,
?int $example = 1,
) {
parent::__construct('offset', 'integer', $description, $required, $example ?? 'No-example');
}
}
23 changes: 23 additions & 0 deletions app/Docs/Attributes/Page.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Docs\Attributes;

use Attribute;
use Knuckles\Scribe\Attributes\GenericParam;

#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class Page extends GenericParam
{
public function __construct(
string $description = 'Search result page',
bool $required = false,
?int $example = 1,
) {
parent::__construct('page', 'integer', $description, $required, $example ?? 'No-example');
}
}
34 changes: 34 additions & 0 deletions app/Docs/Attributes/Sort.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Docs\Attributes;

use Attribute;
use Knuckles\Scribe\Attributes\GenericParam;

#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
class Sort extends GenericParam
{
public function __construct(
array|string $sorts,
?string $defaultText = null,
?string $example = null,
) {
if (is_string($sorts)) {
$hash = mb_strtolower($sorts);
$description = "Sort option as defined in [{$sorts}](#{$hash}).";
} else {
$description = 'Sort order; '.implode(', ', array_map(fn ($sort) => "`{$sort}`", $sorts));
}

if ($defaultText !== null) {
$description .= " {$defaultText}";
}

parent::__construct('sort', 'string', $description, false, $example ?? 'No-example');
}
}
26 changes: 26 additions & 0 deletions app/Docs/Strategies/GetFromQueryParamAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

declare(strict_types=1);

namespace App\Docs\Strategies;

use App\Docs\Attributes\Limit;
use App\Docs\Attributes\Offset;
use App\Docs\Attributes\Page;
use App\Docs\Attributes\Sort;
use Http\Message\Authentication\QueryParam;
use Knuckles\Scribe\Extracting\Strategies\GetParamsFromAttributeStrategy;

class GetFromQueryParamAttribute extends GetParamsFromAttributeStrategy
{
protected static array $attributeNames = [
Limit::class,
Offset::class,
Page::class,
QueryParam::class,
Sort::class,
];
}
17 changes: 10 additions & 7 deletions app/Http/Controllers/BeatmapDiscussionPostsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

namespace App\Http\Controllers;

use App\Docs\Attributes\Limit;
use App\Docs\Attributes\Page;
use App\Docs\Attributes\Sort;
use App\Exceptions\ModelNotSavedException;
use App\Libraries\BeatmapsetDiscussion\Discussion;
use App\Libraries\BeatmapsetDiscussion\Reply;
Expand All @@ -15,6 +18,7 @@
use App\Models\Beatmapset;
use App\Models\BeatmapsetWatch;
use App\Models\User;
use Knuckles\Scribe\Attributes\QueryParam;

/**
* @group Beatmapset Discussions
Expand Down Expand Up @@ -63,14 +67,13 @@ public function destroy($id)
* posts | [BeatmapsetDiscussionPost](#beatmapsetdiscussionpost)[] | |
* users | [User](#user) | |
*
* @queryParam beatmapset_discussion_id `id` of the [BeatmapsetDiscussion](#beatmapsetdiscussion).
* @queryParam limit Maximum number of results.
* @queryParam page Search result page.
* @queryParam sort `id_desc` for newest first; `id_asc` for oldest first. Defaults to `id_desc`.
* @queryParam types[] `first`, `reply`, `system` are the valid values. Defaults to `reply`.
* @queryParam user The `id` of the [User](#user).
* @queryParam with_deleted This param has no effect as api calls do not currently receive group permissions.
* @usesCursor
* @queryParam beatmapset_discussion_id integer `id` of the [BeatmapsetDiscussion](#beatmapsetdiscussion).
* @queryParam types string[] `first`, `reply`, `system` are the valid values. Defaults to `reply`.
* @queryParam user integer The `id` of the [User](#user).
* @queryParam with_deleted boolean This param has no effect as api calls do not currently receive group permissions. No-example
*/
#[Limit(BeatmapDiscussionPost::PER_PAGE, 5), Page, Sort('IdSort')]
public function index()
{
$bundle = new BeatmapsetDiscussionPostsBundle(request()->all());
Expand Down
21 changes: 11 additions & 10 deletions app/Http/Controllers/BeatmapDiscussionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

namespace App\Http\Controllers;

use App\Docs\Attributes\Limit;
use App\Docs\Attributes\Page;
use App\Docs\Attributes\Sort;
use App\Exceptions\ModelNotSavedException;
use App\Libraries\BeatmapsetDiscussion\Review;
use App\Libraries\BeatmapsetDiscussionsBundle;
Expand Down Expand Up @@ -90,17 +93,15 @@ public function destroy($id)
* users | [User](#user)[] | List of users associated with the discussions returned.
*
* @usesCursor
* @queryParam beatmap_id `id` of the [Beatmap](#beatmap).
* @queryParam beatmapset_id `id` of the [Beatmapset](#beatmapset).
* @queryParam beatmapset_status One of `all`, `ranked`, `qualified`, `disqualified`, `never_qualified`. Defaults to `all`. TODO: better descriptions.
* @queryParam limit Maximum number of results.
* @queryParam message_types[] `suggestion`, `problem`, `mapper_note`, `praise`, `hype`, `review`. Blank defaults to all types. TODO: better descriptions.
* @queryParam only_unresolved `true` to show only unresolved issues; `false`, otherwise. Defaults to `false`.
* @queryParam page Search result page.
* @queryParam sort `id_desc` for newest first; `id_asc` for oldest first. Defaults to `id_desc`.
* @queryParam user The `id` of the [User](#user).
* @queryParam with_deleted This param has no effect as api calls do not currently receive group permissions.
* @queryParam beatmap_id integer `id` of the [Beatmap](#beatmap).
* @queryParam beatmapset_id integer `id` of the [Beatmapset](#beatmapset).
* @queryParam beatmapset_status string One of `all`, `ranked`, `qualified`, `disqualified`, `never_qualified`. Defaults to `all`. TODO: better descriptions. No-example
* @queryParam message_types string[] `suggestion`, `problem`, `mapper_note`, `praise`, `hype`, `review`. Blank defaults to all types. TODO: better descriptions. No-example
* @queryParam only_unresolved boolean `true` to show only unresolved issues; `false`, otherwise. Defaults to `false`.
* @queryParam user integer The `id` of the [User](#user).
* @queryParam with_deleted boolean This param has no effect as api calls do not currently receive group permissions. No-example
*/
#[Limit(BeatmapDiscussion::PER_PAGE, 5), Page, Sort('IdSort')]
public function index()
{
$bundle = new BeatmapsetDiscussionsBundle(request()->all());
Expand Down
24 changes: 12 additions & 12 deletions app/Http/Controllers/BeatmapsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public function attributes($id)
* -------- | ------------------------------------- | -----------
* beatmaps | [BeatmapExtended](#beatmapextended)[] | Includes `beatmapset` (with `ratings`), `failtimes`, and `max_combo`.
*
* @queryParam ids[] integer Beatmap IDs to be returned. Specify once for each beatmap ID requested. Up to 50 beatmaps can be requested at once. Example: 1
* @queryParam ids integer[] Beatmap IDs to be returned. Specify once for each beatmap ID requested. Up to 50 beatmaps can be requested at once. Example: [1]
*
* @response {
* "beatmaps": [
Expand Down Expand Up @@ -241,9 +241,9 @@ public function index()
*
* See [Get Beatmap](#get-beatmap)
*
* @queryParam checksum A beatmap checksum.
* @queryParam filename A filename to lookup.
* @queryParam id A beatmap ID to lookup.
* @queryParam checksum string A beatmap checksum. No-example
* @queryParam filename string A filename to lookup. No-example
* @queryParam id integer A beatmap ID to lookup. No-example
*
* @response "See Beatmap object section"
*/
Expand Down Expand Up @@ -342,9 +342,9 @@ public function show($id)
* @urlParam beatmap integer required Id of the [Beatmap](#beatmap).
*
* @queryParam legacy_only integer Whether or not to exclude lazer scores. Defaults to 0. Example: 0
* @queryParam mode The [Ruleset](#ruleset) to get scores for.
* @queryParam mods An array of matching Mods, or none // TODO.
* @queryParam type Beatmap score ranking type // TODO.
* @queryParam mode The [Ruleset](#ruleset) to get scores for. Example: osu
* @queryParam mods string[] An array of matching Mods, or none // TODO. No-example
* @queryParam type string Beatmap score ranking type // TODO. No-example
*/
public function scores($id)
{
Expand All @@ -369,9 +369,9 @@ public function scores($id)
*
* @urlParam beatmap integer required Id of the [Beatmap](#beatmap).
*
* @queryParam mode The [Ruleset](#ruleset) to get scores for.
* @queryParam mods An array of matching Mods, or none // TODO.
* @queryParam type Beatmap score ranking type // TODO.
* @queryParam mode string The [Ruleset](#ruleset) to get scores for. Example: osu
* @queryParam mods string[] An array of matching Mods, or none // TODO.
* @queryParam type string Beatmap score ranking type // TODO. No-example
*/
public function soloScores($id)
{
Expand Down Expand Up @@ -422,8 +422,8 @@ public function updateOwner($id)
* @urlParam user integer required Id of the [User](#user).
*
* @queryParam legacy_only integer Whether or not to exclude lazer scores. Defaults to 0. Example: 0
* @queryParam mode The [Ruleset](#ruleset) to get scores for.
* @queryParam mods An array of matching Mods, or none // TODO.
* @queryParam mode string The [Ruleset](#ruleset) to get scores for. Example: osu
* @queryParam mods string[] An array of matching Mods, or none // TODO. No-example
*/
public function userScore($beatmapId, $userId)
{
Expand Down
19 changes: 11 additions & 8 deletions app/Http/Controllers/BeatmapsetDiscussionVotesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

namespace App\Http\Controllers;

use App\Docs\Attributes\Limit;
use App\Docs\Attributes\Page;
use App\Docs\Attributes\Sort;
use App\Libraries\BeatmapsetDiscussionVotesBundle;
use App\Models\BeatmapDiscussionVote;

/**
* @group Beatmapset Discussions
Expand Down Expand Up @@ -39,15 +43,14 @@ public function __construct()
* users | [User](#user) | |
* votes | [BeatmapsetDiscussionVote](#beatmapsetdiscussionvote)[] | |
*
* @queryParam beatmapset_discussion_id `id` of the [BeatmapsetDiscussion](#beatmapsetdiscussion).
* @queryParam limit Maximum number of results.
* @queryParam page Search result page.
* @queryParam receiver The `id` of the [User](#user) receiving the votes.
* @queryParam score `1` for up vote, `-1` for down vote.
* @queryParam sort `id_desc` for newest first; `id_asc` for oldest first. Defaults to `id_desc`.
* @queryParam user The `id` of the [User](#user) giving the votes.
* @queryParam with_deleted This param has no effect as api calls do not currently receive group permissions.
* @usesCursor
* @queryParam beatmapset_discussion_id integer `id` of the [BeatmapsetDiscussion](#beatmapsetdiscussion).
* @queryParam receiver integer The `id` of the [User](#user) receiving the votes.
* @queryParam score integer `1` for up vote, `-1` for down vote. Example: 1
* @queryParam user integer The `id` of the [User](#user) giving the votes.
* @queryParam with_deleted boolean This param has no effect as api calls do not currently receive group permissions. No-example
*/
#[Limit(BeatmapDiscussionVote::PER_PAGE, 5), Page, Sort('IdSort')]
public function index()
{
$bundle = new BeatmapsetDiscussionVotesBundle(request()->all());
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/ChangelogController.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private static function changelogEntryMessageIncludes(?array $formats): array
* @queryParam max_id integer Maximum build ID. No-example
* @queryParam stream string Stream name to return builds from. No-example
* @queryParam to string Maximum build version. No-example
* @queryParam message_formats[] string `html`, `markdown`. Default to both.
* @queryParam message_formats[] string `html`, `markdown`. Default to both. No-example
* @response {
* "streams": [
* {
Expand Down Expand Up @@ -244,7 +244,7 @@ public function github()
*
* @urlParam changelog string required Build version, update stream name, or build ID. Example: 20210520.2
* @queryParam key string Unset to query by build version or stream name, or `id` to query by build ID. No-example
* @queryParam message_formats[] string `html`, `markdown`. Default to both.
* @queryParam message_formats string[] `html`, `markdown`. Default to both.
* @response See "Get Changelog Build" response.
*/
public function show($version)
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Controllers/Chat/Channels/MessagesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace App\Http\Controllers\Chat\Channels;

use App\Docs\Attributes\Limit;
use App\Http\Controllers\Chat\Controller as BaseController;
use App\Libraries\Chat;
use App\Models\Chat\Channel;
Expand Down Expand Up @@ -37,7 +38,6 @@ public function __construct()
* Returns an array of [ChatMessage](#chatmessage)
*
* @urlParam channel integer required The ID of the channel to retrieve messages for
* @queryParam limit integer number of messages to return (max of 50)
* @queryParam since integer messages after the specified message id will be returned
* @queryParam until integer messages up to but not including the specified message id will be returned
*
Expand Down Expand Up @@ -82,6 +82,7 @@ public function __construct()
* }
* ]
*/
#[Limit]
public function index($channelId)
{
[
Expand Down
10 changes: 8 additions & 2 deletions app/Http/Controllers/Chat/ChannelsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ public function join($channelId, $userId)
* This endpoint will only allow the leaving of public channels initially.
* </aside>
*
* @urlParam channel integer required `channel_id` of the [ChatChannel](#chatchannel) to leave.
* @urlParam user integer required `id` of the [User](#user) to leave the channel.
*
* @response 204
*/
public function part($channelId, $userId)
Expand Down Expand Up @@ -146,6 +149,8 @@ public function part($channelId, $userId)
* channel | [ChatChannel](#chatchannel) | |
* users | [User](#user) | Users are only visible for PM channels.
*
* @urlParam channel integer required `channel_id` of the [ChatChannel](#chatchannel) to get.
*
* @response {
* "channel": {
* "channel_id": 1337,
Expand Down Expand Up @@ -191,6 +196,7 @@ public function part($channelId, $userId)
* }
* ]
* }
*
*/
public function show($channelId)
{
Expand Down Expand Up @@ -314,8 +320,8 @@ public function store()
* Note that the read marker cannot be moved backwards - i.e. if a channel has been marked as read up to <code>message_id = 12</code>, you cannot then set it backwards to <code>message_id = 10</code>. It will be rejected.
* </aside>
*
* @queryParam channel_id required The `channel_id` of the channel to mark as read
* @queryParam message_id required The `message_id` of the message to mark as read up to
* @urlParam channel integer required The `channel_id` of the [ChatChannel](#chatchannel) to mark as read.
* @urlParam message integer required The `message_id` of the [ChatMessage](#chatmessage) to mark as read up to.
*
* @response 204
*/
Expand Down
Loading