-
-
Notifications
You must be signed in to change notification settings - Fork 4
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
refactor(api_apub): update openapi docs #71
Conversation
WalkthroughThe changes encompass multiple modifications across various files in the Changes
Assessment against linked issues
Possibly related PRs
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (10)
crates/api_apub/src/users/user_inbox.rs (1)
12-25
: OpenAPI documentation is well-structured and comprehensive.The OpenAPI documentation for the user inbox endpoint is clear and covers all necessary aspects:
- HTTP method (POST) and path are correctly specified.
- Responses include appropriate status codes (OK, NOT_FOUND, INTERNAL_SERVER_ERROR).
- The parameter for "user" is well-described.
Consider adding a brief description of the endpoint's purpose at the beginning of the documentation, e.g.:
/// User inbox /// /// Handles incoming activities for a user's inbox. #[utoipa::path( // ... (rest of the documentation) )]This would provide a quick overview of the endpoint's functionality.
crates/api_apub/src/posts/notice.rs (1)
19-19
: Consider removing#[debug_handler]
for production use.The
#[debug_handler]
attribute is typically used for debugging purposes. If this endpoint is intended for production use, consider removing this attribute to ensure optimal performance and avoid any potential debug-related side effects.crates/api_apub/src/users/mod.rs (2)
2-3
: LGTM! Consider adding documentation for thePagination
struct.The new
Pagination
struct and its imports look good. The struct is correctly derived fromDeserialize
andIntoParams
, which are appropriate for query parameters and OpenAPI documentation.Consider adding documentation comments to the
Pagination
struct and itspage
field to provide more context for API users. For example:/// Represents pagination parameters for API requests. #[derive(Deserialize, IntoParams)] pub struct Pagination { /// The page number to retrieve. If not provided, defaults to the first page. page: Option<u64>, }Also applies to: 13-16
21-24
: LGTM! Consider updating fallback routes for consistency.The updated routing logic using the
routes!
macro improves code readability and aligns well with the OpenAPI documentation approach. This change maintains the same functionality while making the code more concise.For consistency, consider updating the fallback routes to use the
routes!
macro as well. This would make the entireroutes()
function more uniform. Here's an example of how you could refactor the fallback routes:pub fn routes() -> OpenApiRouter { OpenApiRouter::with_openapi(ApubApi::openapi()) .routes(routes!( user::handler, user_followers::handler, user_following::handler, user_inbox::handler, user_outbox::handler, user::redirect, user_followers::redirect, user_following::redirect, user_outbox::redirect, user_inbox::handler )) }This change would require updating the handler functions to include the appropriate path and method attributes, but it would result in a more consistent and maintainable routing structure.
crates/api_apub/src/lib.rs (1)
29-32
: LGTM: New OpenAPI components added.The addition of
Collection
,CollectionOrPage
,CollectionPage<Url>
, andCollectionPage<Value>
components enhances the API's schema definitions, supporting improved collection and pagination handling.Consider adding brief documentation comments for these new components to explain their purpose and usage within the API. This will help other developers understand how to use these structures correctly.
crates/apub/src/collections/collection.rs (1)
9-25
: LGTM: Well-structured Collection struct with appropriate attributes.The
Collection
struct is well-defined and aligns with the ActivityPub OrderedCollection object. The use of derive macros and serde attributes demonstrates good practices for API development and serialization.Consider adding doc comments (
///
) for each field to provide more detailed descriptions. This would enhance the generated documentation and make the struct's purpose clearer to other developers. For example:/// Represents an ActivityPub OrderedCollection #[derive(Clone, Debug, Deserialize, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct Collection { /// The type of the collection, always "OrderedCollection" #[serde(rename = "type")] kind: OrderedCollectionType, /// The unique identifier for the collection /// example: https://hatsu.local/users/example.com/collection id: Url, // ... (add similar comments for other fields) }crates/apub/src/collections/collection_page.rs (2)
9-28
: LGTM: Well-structured CollectionPage definition with appropriate attributes.The
CollectionPage<T>
struct is well-designed and aligns with the ActivityPub protocol's collection page structure. The use of generics provides flexibility, and the serde attributes are correctly applied for JSON serialization control.Consider adding documentation comments (///) for the struct and its fields to improve code readability and generate more comprehensive API documentation.
30-57
: LGTM: Solid implementation of CollectionPage constructor with proper pagination handling.The
new
method effectively constructs aCollectionPage
instance, handling pagination logic correctly. The use ofResult
for error handling is commendable.
- Consider translating the Chinese comment on line 41 to English for consistency.
- It might be beneficial to add input validation for the
page
parameter to ensure it's not greater thantotal_pages
.Consider extracting the URL generation logic for
prev
andnext
into separate private methods to improve readability and maintainability. For example:impl<T> CollectionPage<T> { fn generate_prev_url(&self, collection_id: &Url, page: u64) -> Result<Option<Url>, AppError> { if page > 1 { Some(generate_collection_page_url(collection_id, page - 1)).transpose() } else { Ok(None) } } fn generate_next_url(&self, collection_id: &Url, page: u64, total_pages: u64) -> Result<Option<Url>, AppError> { if page < total_pages { Some(generate_collection_page_url(collection_id, page + 1)).transpose() } else { Ok(None) } } pub fn new( collection_id: Url, total_items: u64, ordered_items: Vec<T>, total_pages: u64, page: u64, ) -> Result<Self, AppError> { Ok(Self { kind: OrderedCollectionPageType::OrderedCollectionPage, id: Url::parse_with_params(collection_id.as_ref(), &[("page", page.to_string())])?, prev: self.generate_prev_url(&collection_id, page)?, next: self.generate_next_url(&collection_id, page, total_pages)?, part_of: collection_id, ordered_items, total_items, }) } }This refactoring improves readability and makes the
new
method more concise.crates/api_apub/src/users/user_following.rs (1)
27-27
: Clarify the parameter description for 'user'.The description currently reads "The Domain of the User in the database." If
name
represents the username, consider updating the description to "The username of the user." This provides clearer information for API consumers.Apply this diff to update the description:
- ("user" = String, Path, description = "The Domain of the User in the database."), + ("user" = String, Path, description = "The username of the user."),crates/api_apub/src/users/user_outbox.rs (1)
41-41
: Consider providing a default value for pagination.The
pagination
parameter is now required in the handler function. Consider providing a default value for thePagination
struct to avoid breaking existing clients that may not provide pagination parameters.Apply this diff to provide a default value for
Pagination
:- pagination: Query<Pagination>, + pagination: Option<Query<Pagination>>,Then, update the usage of
pagination
in the handler function:- match pagination.page { + match pagination.as_ref().map(|p| p.page).unwrap_or(None) {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (12)
- crates/api_apub/src/lib.rs (2 hunks)
- crates/api_apub/src/posts/mod.rs (1 hunks)
- crates/api_apub/src/posts/notice.rs (1 hunks)
- crates/api_apub/src/users/mod.rs (2 hunks)
- crates/api_apub/src/users/user_followers.rs (4 hunks)
- crates/api_apub/src/users/user_following.rs (1 hunks)
- crates/api_apub/src/users/user_inbox.rs (1 hunks)
- crates/api_apub/src/users/user_outbox.rs (4 hunks)
- crates/apub/src/collections/collection.rs (1 hunks)
- crates/apub/src/collections/collection_page.rs (1 hunks)
- crates/apub/src/collections/mod.rs (2 hunks)
- crates/backend/src/openapi.rs (1 hunks)
🔇 Additional comments (29)
crates/backend/src/openapi.rs (1)
4-4
: Clarify the removal of API paths from OpenAPI documentationThe
paths
attribute has been removed from the#[openapi]
macro. While this simplifies the struct declaration, it raises some concerns:
- The API endpoints, specifically
hatsu_api_apub::posts::post::post
, are no longer explicitly documented here.- This change might not fully address the goal of writing utoipa documentation for apub posts (issue Write utoipa documentation for apub posts #66).
Could you please clarify:
- Where are the API endpoints now documented?
- How does this change align with the objective of improving documentation for apub posts?
Consider adding a comment explaining the rationale behind this change and directing readers to where they can find the complete API documentation.
To ensure we haven't missed any API documentation, let's search for other potential locations:
✅ Verification successful
API Paths Documentation is Distributed Across Modules
The removal of the
paths
attribute from the#[openapi]
macro incrates/backend/src/openapi.rs
appears to be intentional and aligns with the distributed approach to API documentation.Based on the search results:
- API endpoints are documented using
#[utoipa::path]
and#[openapi]
annotations in multiple files across different crates.- This modular documentation strategy ensures that each module maintains its own API definitions, enhancing maintainability and clarity.
Therefore, the change does not compromise the API documentation but rather organizes it more effectively.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for OpenAPI or utoipa documentation in other files rg --type rust -e '#\[openapi' -e '#\[utoipa::path' -e 'impl utoipa::OpenApi'Length of output: 1984
crates/api_apub/src/posts/mod.rs (2)
Line range hint
9-15
: LGTM! Verify OpenAPI documentation for the routes.The routing configuration correctly includes the
notice
route and maintains the existing routes for posts. The use ofOpenApiRouter
withApubApi::openapi()
suggests that these routes are documented in the OpenAPI specification.To ensure that the OpenAPI documentation is up-to-date with these routes, please run the following script:
#!/bin/bash # Description: Check for OpenAPI documentation of the routes # Search for OpenAPI documentation related to these routes rg --type rust "utoipa::path" -A 10 -g "crates/api_apub/src/**/*.rs"Review the output to confirm that all routes (
/notice/*notice
,/posts/*post
, and/p/*post
) are properly documented in the OpenAPI specification.
7-7
: LGTM! Verify the usage of thenotice
module.The
notice
module is now public, which aligns with the PR objectives of updating the OpenAPI documentation. This change allows other parts of the crate or external crates to access its contents.To ensure this change is intentional and properly utilized, please run the following script to check for any usage of the
notice
module outside its original scope:If there are no results, consider whether making the module public is necessary for future use or documentation purposes.
✅ Verification successful
Please run the following corrected script to check for any usage of the
notice
module outside its original scope:
Verified: The
notice
module is used outside its original scope.
- Usage found in
crates/api_apub/src/lib.rs
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for usage of the `notice` module outside its original scope # Search for imports of the notice module rg --type rust "use .*notice" --glob '!crates/api_apub/src/posts/mod.rs' # Search for direct usage of the notice module rg --type rust "posts::notice" --glob '!crates/api_apub/src/posts/mod.rs'Length of output: 6470
Script:
# #!/bin/bash # Description: Check for usage of the `notice` module outside its original scope # Search for imports of the notice module excluding the target file rg --type rust "use\s+.*notice" --glob '!crates/api_apub/src/posts/mod.rs' # Search for direct usage of the notice module excluding the target file rg --type rust "posts::notice" --glob '!crates/api_apub/src/posts/mod.rs'Length of output: 208
crates/api_apub/src/users/user_inbox.rs (3)
Line range hint
1-10
: Imports look good and cover all necessary dependencies.The imports are comprehensive and include all required dependencies for the new handler function. The addition of
TAG
from the crate root is appropriate for use in the OpenAPI documentation.
Line range hint
26-29
: Handler function implementation looks correct and aligns with documentation.The
handler
function is well-implemented:
- It's correctly marked with
#[debug_handler]
for development purposes.- The function signature matches the OpenAPI documentation.
- The use of
receive_activity
with appropriate generic types (WithContext<UserInboxActivities>
,ApubUser
,AppData
) is correct for handling user inbox activities.
Line range hint
1-29
: Overall, the changes successfully implement and document the user inbox endpoint.This implementation aligns well with the PR objectives of updating OpenAPI documentation for the API. The new endpoint for handling user inbox activities is properly implemented and thoroughly documented using utoipa. The changes enhance the API's functionality and improve its documentation, making it easier for developers to understand and use the user inbox feature.
crates/api_apub/src/posts/notice.rs (2)
1-18
: LGTM: Imports and OpenAPI documentation are well-structured.The imports are appropriate for the functionality, and the OpenAPI documentation is comprehensive. It correctly specifies the HTTP method, path, expected responses, and parameters. The use of the
TAG
constant suggests consistent tagging across the API, which is a good practice.
Line range hint
20-32
: LGTM: Function implementation is robust and efficient.The implementation correctly handles base64 decoding and URL validation. The use of
base64_simd
for decoding is a good choice for performance. The error handling is appropriate, returning a not found error for invalid inputs.However, please verify that the redirect URL format
/posts/{url}
is correct and consistent with the rest of the API. Run the following script to check for similar redirect patterns:✅ Verification successful
Please run the following script to further verify the route definitions for
/posts/
in the codebase:
Verified: Redirect URL format
/posts/{url}
is consistent with existing route definitions.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for similar redirect patterns in the codebase # Search for Redirect::permanent calls echo "Searching for Redirect::permanent calls:" rg --type rust 'Redirect::permanent\(' -A 1 # Search for route definitions with '/posts/' prefix echo "Searching for route definitions with '/posts/' prefix:" rg --type rust '#\[utoipa::path\(.*path\s*=\s*"/posts/.*"\)' -A 5Length of output: 1392
Script:
#!/bin/bash # Description: Further verify route definitions with '/posts/' prefix by broadening the search pattern # Search for utoipa::path attributes with '/posts/' in any format echo "Searching for utoipa::path attributes with '/posts/' prefix:" rg --type rust '\\#\\[utoipa::path.*path\\s*=\\s*".*/posts/.*"\\]' -A 5 # Additionally, search for any route annotations that might define '/posts/' paths echo "Searching for any route definitions containing '/posts/':" rg --type rust 'path\s*=\s*".*/posts/.*"' -A 5Length of output: 797
crates/api_apub/src/users/mod.rs (1)
Line range hint
1-31
: Overall changes align well with PR objectives.The modifications in this file, including the introduction of the
Pagination
struct and the use of theroutes!
macro, contribute significantly to improving the API documentation and code maintainability. These changes directly address the PR's objective of updating OpenAPI documentation for the API.The
Pagination
struct provides a clear structure for handling paginated requests, while theroutes!
macro simplifies the routing logic, making it more readable and easier to maintain. Both of these changes will result in better-documented and more understandable API endpoints.crates/api_apub/src/lib.rs (2)
3-3
: LGTM: New imports align with OpenAPI updates.The added imports for
Collection
,CollectionOrPage
,CollectionPage
,Value
, andUrl
are consistent with the new OpenAPI components and likely support the expanded API functionality.Also applies to: 7-8
Line range hint
1-53
: LGTM: File structure and changes are consistent and well-integrated.The modifications to this file are well-structured and align with the PR objectives. The new imports, OpenAPI paths, and components are integrated seamlessly with the existing code. The overall file structure remains consistent and maintainable.
crates/apub/src/collections/collection.rs (2)
1-7
: LGTM: Imports are appropriate and well-organized.The imports cover all necessary dependencies for implementing an ActivityPub collection, including serialization, URL handling, and OpenAPI documentation generation. The local import of
generate_collection_page_url
suggests good modularization of the codebase.
1-50
: Summary: Good implementation of ActivityPub Collection, aligns with PR objectivesThis new file introduces a well-structured
Collection
struct and its implementation, which aligns with the ActivityPub protocol specifications. The code contributes to the PR's objective of updating OpenAPI docs (via theToSchema
derive) and addresses issue #66 by providing a foundation for handling ActivityPub collections in the API.The implementation is generally solid, with good use of Rust features and external crates. We've suggested a few minor improvements:
- Adding more detailed documentation comments to the struct fields.
- Fixing a small logic issue in the last page URL generation.
- Adding input validation in the
new
method to ensure consistency betweentotal_items
andtotal_pages
.These changes will enhance the robustness and clarity of the code, further supporting the PR's objectives.
crates/apub/src/collections/collection_page.rs (2)
1-8
: LGTM: Imports are appropriate and well-organized.The imports cover all necessary dependencies for the implementation, including ActivityPub federation types, error handling, serialization, URL manipulation, and OpenAPI documentation generation.
1-57
: Summary: CollectionPage implementation aligns well with PR objectivesThis new file introduces a
CollectionPage
struct and its implementation, which directly contributes to the PR's objective of updating OpenAPI documentation and enhancing the API's collection handling capabilities. The code is well-structured and aligns with ActivityPub protocol requirements.The implementation of
CollectionPage
provides a solid foundation for documenting and handling paginated collections, which is crucial for addressing issue #66 ("Write utoipa documentation for apub posts"). The use of theToSchema
derive macro ensures that this struct can be easily integrated into the OpenAPI documentation.While the implementation is generally strong, consider the suggested improvements to further enhance code quality and maintainability:
- Add documentation comments for the struct and its fields.
- Translate the Chinese comment to English for consistency.
- Consider refactoring the URL generation logic for improved readability.
These changes will further improve the codebase and make it easier for other developers to understand and maintain the API documentation.
crates/api_apub/src/users/user_following.rs (2)
34-34
: Ensure 'Pagination' handles default values for missing query parameters.By changing the handler's signature from accepting an optional
Query<Pagination>
to a mandatoryQuery<Pagination>
, it's important to ensure thatPagination
can handle cases where query parameters are not provided by clients. This ensures backward compatibility and prevents potential errors when clients omit pagination parameters.Run the following script to verify that
Pagination
handles default values:
39-54
:⚠️ Potential issueVerify the correctness of URL construction in 'Collection' and 'CollectionPage'.
The URLs are constructed by joining
generate_user_url(data.domain(), &name)?
with&format!("{name}/following")
. There is a potential risk of duplicating the username in the URL, resulting in incorrect URLs likehttps://example.com/users/username/username/following
. Ensure that the URL construction results in the correct endpoint.Run the following script to check the generated URLs for a sample user:
✅ Verification successful
URL construction is correct and does not duplicate the username.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that URL generation does not duplicate the username. # Test: Print the generated URLs for a sample username and inspect the output. echo "Testing URL generation for user 'alice':" echo "Base URL:" hatsu_utils_url=$(rg --no-heading --no-filename --type rust 'fn generate_user_url' -A 10 | grep -Po '(?<=return ).*(?=;)') echo "$hatsu_utils_url" echo "Generated URL:" echo "$hatsu_utils_url.join(\"alice/following\")"Length of output: 361
Script:
#!/bin/bash # Description: Extract the implementation of `generate_user_url` function. # Find the file where `generate_user_url` is defined file_path=$(rg --files-with-matches 'fn generate_user_url' --type rust | head -n 1) if [ -z "$file_path" ]; then echo "generate_user_url function not found in the codebase." exit 1 fi echo "Implementation of generate_user_url in $file_path:" rg --before-context=5 --after-context=20 'fn generate_user_url' "$file_path"Length of output: 1121
Script:
#!/bin/bash # Description: Extract all return statements within `generate_user_url` function. # Find the file where `generate_user_url` is defined file_path=$(rg --files-with-matches 'fn generate_user_url' --type rust | head -n 1) if [ -z "$file_path" ]; then echo "generate_user_url function not found in the codebase." exit 1 fi echo "Return statements in generate_user_url:" rg --no-heading --no-filename 'return .*;' "$file_path" | grep 'fn generate_user_url' -A 10Length of output: 353
Script:
#!/bin/bash # Description: Extract the URL format string used in `Url::parse` within `generate_user_url`. # Find the file where `generate_user_url` is defined file_path=$(rg --files-with-matches 'fn generate_user_url' --type rust | head -n 1) if [ -z "$file_path" ]; then echo "generate_user_url function not found in the codebase." exit 1 fi echo "URL format strings in generate_user_url:" rg --no-heading --no-filename 'Url::parse(&format!' "$file_path" | grep -Po '(?<=")[^"]+'Length of output: 434
Script:
#!/bin/bash # Description: Check for instances where the username might be duplicated in URL construction. # Find the file where `generate_user_url` is defined file_path=$(rg --files-with-matches 'fn generate_user_url' --type rust | head -n 1) if [ -z "$file_path" ]; then echo "generate_user_url function not found in the codebase." exit 1 fi echo "Checking for potential username duplication in URL construction:" rg --no-heading --no-filename 'generate_user_url' "$file_path" | rg 'join'Length of output: 382
Script:
#!/bin/bash # Description: Extract the format strings used in `Url::parse` within `generate_user_url`. # Find the file where `generate_user_url` is defined file_path=$(rg --files-with-matches 'fn generate_user_url' --type rust | head -n 1) if [ -z "$file_path" ]; then echo "generate_user_url function not found in the codebase." exit 1 fi echo "Format strings used in Url::parse within generate_user_url:" rg --no-heading --no-filename 'Url::parse\s*\(&\s*format!' "$file_path" | grep -Po '".+?"'Length of output: 471
Script:
#!/bin/bash # Description: Analyze URL concatenation in user_following.rs to check for username duplication. # File to analyze target_file="crates/api_apub/src/users/user_following.rs" if [ ! -f "$target_file" ]; then echo "File $target_file does not exist." exit 1 fi echo "Analyzing URL concatenation in $target_file:" rg 'generate_user_url' "$target_file" | rg 'join' --context=2Length of output: 368
crates/api_apub/src/users/user_followers.rs (6)
23-36
: Great job documenting the API endpoint!The utoipa documentation provides clear information about the endpoint, including the HTTP method, path, responses, and parameters. This will greatly enhance the usability and understanding of the API.
40-40
: Verify the impact of changingOption<Query<Pagination>>
toQuery<Pagination>
.Changing the parameter type from
Option<Query<Pagination>>
toQuery<Pagination>
means that the pagination query parameter is now required. Ensure that this change is intentional and that all callers of this endpoint have been updated to provide the necessary pagination information.Run the following script to verify the usage of the
handler
function:#!/bin/bash # Description: Verify the usage of the `handler` function. # Test: Search for calls to the `handler` function. # Expect: All calls provide the required `pagination` argument. rg --type rust -A 5 $'user_followers::handler'
21-21
: Verify the import ofPagination
from theusers
module.Ensure that the
Pagination
struct is defined correctly in theusers
module and that the import statement is valid.Run the following script to verify the import:
#!/bin/bash # Description: Verify the import of `Pagination` from the `users` module. # Test: Search for the `Pagination` struct definition in the `users` module. # Expect: The struct definition exists. rg --type rust -A 5 $'struct Pagination' crates/api_apub/src/users
42-42
: Verify the usage ofFederationJson<WithContext<CollectionOrPage>>
in the codebase.The return type of the handler has been updated to
Result<FederationJson<WithContext<CollectionOrPage>>, AppError>
. Ensure that all code paths that call this handler are expecting and handling the new return type correctly.Run the following script to verify the usage of the new return type:
#!/bin/bash # Description: Verify the usage of `FederationJson<WithContext<CollectionOrPage>>` in the codebase. # Test: Search for the new return type. # Expect: Usage in relevant code paths that call the `handler` function. rg --type rust -A 5 $'FederationJson<WithContext<CollectionOrPage>>'
58-63
: Verify the construction ofCollectionOrPage::Collection
.Ensure that the
Collection
variant ofCollectionOrPage
is constructed correctly, with the appropriate URL, total items, and total pages. Verify that the URL generation logic is correct and handles any potential errors.Run the following script to verify the
Collection
construction:#!/bin/bash # Description: Verify the construction of `CollectionOrPage::Collection`. # Test: Search for the construction of `CollectionOrPage::Collection`. # Expect: Correct URL generation and handling of potential errors. rg --type rust -A 5 $'CollectionOrPage::Collection'
Line range hint
73-86
: Verify the construction ofCollectionOrPage::CollectionPageUrl
.Ensure that the
CollectionPageUrl
variant ofCollectionOrPage
is constructed correctly, with the appropriate URL, total items, page items, total pages, and current page. Verify that the URL generation logic is correct and handles any potential errors. Also, ensure that thefollower_pages
pagination logic is correct and fetches the desired page of followers.Run the following script to verify the
CollectionPageUrl
construction:#!/bin/bash # Description: Verify the construction of `CollectionOrPage::CollectionPageUrl`. # Test: Search for the construction of `CollectionOrPage::CollectionPageUrl`. # Expect: Correct URL generation, pagination logic, and handling of potential errors. rg --type rust -A 10 $'CollectionOrPage::CollectionPageUrl'crates/api_apub/src/users/user_outbox.rs (6)
24-37
: Great job documenting the API endpoint!The utoipa documentation for the user outbox endpoint is comprehensive and follows the OpenAPI specification. It clearly describes the endpoint, its parameters, and the expected responses.
43-43
: Verify the usage ofCollectionOrPage
in the response.The return type of the handler function has been updated to use
CollectionOrPage
in the response. Ensure that the code constructing the response correctly uses theCollectionOrPage
enum variants.Manually review the code constructing the response to ensure the correct usage of
CollectionOrPage
enum variants.
61-66
: LGTM!The usage of
CollectionOrPage::Collection
variant for constructing the response when no pagination is provided is correct.
Line range hint
76-92
: LGTM!The usage of
CollectionOrPage::CollectionPageValue
variant for constructing the response when a specific page is requested is correct. The pagination logic handles the case when the requested page is out of bounds and returns an appropriate error.
22-22
: Verify the import ofPagination
struct.The
Pagination
struct is now imported from another module. Ensure that the struct definition in the source module matches the usage in this file.Run the following script to verify the
Pagination
struct definition:✅ Verification successful
Import of
Pagination
struct verified successfully.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the `Pagination` struct definition. # Test: Search for the `Pagination` struct definition. Expect: Struct definition that matches the usage. rg --type rust -A 5 $'struct Pagination'Length of output: 376
Script:
#!/bin/bash # Description: Verify usages of the `Pagination` struct in user_outbox.rs. # Search for all instances where `Pagination` is used. rg --type rust 'Pagination' crates/api_apub/src/users/user_outbox.rs -A 5Length of output: 571
15-15
: Verify the usage ofCollectionOrPage
in the codebase.The introduction of the
CollectionOrPage
enum is a good change as it allows the handler to return either a full collection or a paginated page. However, ensure that the code consuming this API endpoint is updated to handle both variants of the enum.Run the following script to verify the usage of
CollectionOrPage
:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Outside diff range and nitpick comments (21)
crates/backend/src/openapi.rs (1)
Line range hint
1-6
: Summary of changes and potential impactThe modifications to the
ApiDoc
struct definition simplify the OpenAPI documentation generation. While this aligns with the PR objectives, it's crucial to ensure that all necessary API endpoints are still properly documented.To maintain comprehensive API documentation:
- Verify that the removed
hatsu_api_apub::posts::post::post
path is documented elsewhere or intentionally excluded.- Ensure that this change doesn't result in missing documentation for any critical API endpoints.
- Consider adding a comment explaining the rationale behind this simplification for future maintainers.
Consider implementing a centralized approach to manage OpenAPI documentation across the project. This could involve:
- Creating a dedicated module for OpenAPI configuration.
- Implementing a custom procedural macro to automatically include all relevant paths and components.
- Establishing clear guidelines for documenting new API endpoints to maintain consistency and completeness in the OpenAPI specification.
crates/api_apub/src/posts/mod.rs (2)
Line range hint
10-16
: Enhance OpenAPI documentation for routes.While the routing configuration is correct, consider adding explicit OpenAPI documentation for each route using Utoipa attributes. This will improve the clarity and completeness of the API documentation.
Example of how to add documentation:
/// Get a notice #[utoipa::path( get, path = "/notice/{notice}", responses( (status = 200, description = "Notice found", body = Notice), (status = 404, description = "Notice not found") ), params( ("notice" = String, Path, description = "Notice identifier") ) )] async fn notice(/* ... */) -> impl IntoResponse { // ... }Apply similar documentation to the
post
andredirect
routes as well.
Line range hint
1-16
: Summary: Good progress, but further documentation enhancements recommended.The changes in this file contribute to the PR objective of updating OpenAPI documentation for the
apub
module. Thenotice
module is now public, which should allow for better API documentation. However, to fully meet the PR objectives:
- Add explicit OpenAPI documentation for each route using Utoipa attributes.
- Clarify the status of the Utoipa documentation task that was mentioned in the removed comment.
- Verify that making the
notice
module public doesn't unintentionally expose sensitive information.These steps will ensure comprehensive and accurate API documentation, aligning with the goals outlined in issue #66.
crates/api_apub/src/users/user_inbox.rs (2)
13-25
: LGTM! Consider adding a request body description.The newly added
#[utoipa::path]
attribute provides clear and comprehensive documentation for the user inbox endpoint, aligning well with the PR objectives. The path, HTTP method, responses, and parameters are correctly specified.Consider adding a
request_body
field to the#[utoipa::path]
attribute to describe the expected structure of the incoming activity data. This would provide more complete documentation for API consumers. For example:#[utoipa::path( // ... existing fields ... request_body = ActivityData, // ... remaining fields ... )]Ensure to import or define
ActivityData
in the OpenAPI schema if it's not already included.
Line range hint
26-30
: Verified consistency. Consider adding error handling.The
handler
function implementation is consistent with the newly added OpenAPI documentation. The function signature and parameters align well with the documented endpoint.Consider adding explicit error handling to match the documented NOT_FOUND and INTERNAL_SERVER_ERROR responses. This would improve the robustness of the endpoint and ensure it behaves as documented. For example:
pub async fn handler(data: Data<AppData>, activity_data: ActivityData) -> Result<impl IntoResponse, AppError> { receive_activity::<WithContext<UserInboxActivities>, ApubUser, AppData>(activity_data, &data) .await .map_err(|e| { // Log the error tracing::error!("Error processing inbox activity: {:?}", e); // Map the error to an appropriate AppError variant AppError::InternalServerError }) }This change would require updating the return type and adding appropriate error mapping logic.
crates/api_apub/src/posts/notice.rs (2)
6-18
: LGTM: Comprehensive OpenAPI documentation added.The OpenAPI documentation for the new endpoint is well-structured and follows best practices. It correctly specifies the HTTP method, path, responses, and parameters. This aligns well with the objectives of updating the OpenAPI documentation as mentioned in the PR summary.
Consider adding a brief description of the endpoint's functionality in the OpenAPI documentation. For example:
#[utoipa::path( get, tag = TAG, path = "/notice/{notice}", + summary = "Retrieve a post by its base64-encoded URL", responses( (status = OK, description = "Post", body = Note), (status = NOT_FOUND, description = "Post does not exist", body = AppError) ), params( ("notice" = String, Path, description = "Base64 Post Url") ) )]
This addition would provide users with a quick understanding of the endpoint's purpose.
Line range hint
19-31
: LGTM: Well-implemented notice function with proper error handling.The
notice
function is well-implemented, with appropriate use ofbase64_simd
for efficient decoding and proper error handling. The security check for "https://" URLs is a good practice.Consider separating the error cases for invalid base64 and invalid URL format. This would provide more specific error messages:
pub async fn notice(Path(base64_url): Path<String>) -> Result<Redirect, AppError> { let base64 = base64_simd::URL_SAFE; - base64.decode_to_vec(&base64_url).map_or_else( - |_| Err(AppError::not_found("Record", &base64_url)), - |utf8_url| match String::from_utf8(utf8_url) { - Ok(url) if url.starts_with("https://") => - Ok(Redirect::permanent(&format!("/posts/{url}"))), - _ => Err(AppError::not_found("Record", &base64_url)), - }, - ) + let utf8_url = base64.decode_to_vec(&base64_url) + .map_err(|_| AppError::bad_request("Invalid base64 encoding"))?; + + let url = String::from_utf8(utf8_url) + .map_err(|_| AppError::bad_request("Invalid UTF-8 in decoded URL"))?; + + if url.starts_with("https://") { + Ok(Redirect::permanent(&format!("/posts/{url}"))) + } else { + Err(AppError::bad_request("URL must start with https://")) + } }This change would provide more specific error messages, improving the API's usability.
crates/api_apub/src/users/mod.rs (3)
13-16
: LGTM:Pagination
struct added with appropriate traits.The
Pagination
struct is well-defined and aligns with the PR objective of updating OpenAPI documentation. The use ofOption<u64>
for thepage
field allows for optional pagination, which is a good design choice.Consider adding a doc comment to explain the purpose and usage of this struct, especially since it's public. For example:
/// Represents pagination parameters for API requests. /// `page`: Optional page number for paginated results. #[derive(Deserialize, IntoParams)] pub struct Pagination { pub page: Option<u64>, }
21-24
: LGTM: Routing logic refactored usingroutes!
macro.The refactoring of route definitions using the
routes!
macro improves code conciseness while maintaining functionality. This change aligns well with the PR objective of refactoring and updating the API.For consistency, consider applying the same refactoring to the fallback routes (lines 26-30). This would make the routing logic uniform throughout the function. For example:
pub fn routes() -> OpenApiRouter { OpenApiRouter::with_openapi(ApubApi::openapi()) .routes(routes!( user::handler, user_followers::handler, user_following::handler, user_inbox::handler, user_outbox::handler, user::redirect, user_followers::redirect, user_following::redirect, user_outbox::redirect, user_inbox::handler )) }This suggestion assumes that the
routes!
macro can handle different HTTP methods (GET and POST) correctly. If not, the current mixed approach might be the best solution.
Line range hint
1-30
: Overall assessment: Changes improve code structure and align with PR objectives.The modifications in this file, including the addition of the
Pagination
struct and the refactoring of route definitions, contribute positively to the project's goal of updating OpenAPI documentation and improving code structure. The changes are well-implemented and consistent with best practices.As the project evolves, consider the following architectural suggestions:
- Implement a consistent pagination strategy across all relevant endpoints.
- Document the pagination behavior in the API documentation to ensure clear understanding for API consumers.
- Consider implementing rate limiting alongside pagination to further protect your API from potential abuse.
crates/apub/src/collections/collection.rs (2)
9-25
: LGTM: Well-structured Collection struct with a minor suggestion.The
Collection
struct is well-defined and aligns with ActivityPub collection requirements. It makes good use of derive macros and serde attributes for serialization and documentation.Consider adding doc comments (
///
) instead of regular comments for better documentation:- // example: https://hatsu.local/users/example.com/collection + /// Example: https://hatsu.local/users/example.com/collection id: Url, - // example: https://hatsu.local/users/example.com/collection?page=1 + /// Example: https://hatsu.local/users/example.com/collection?page=1 first: Url, - // example: https://hatsu.local/users/example.com/collection?page=64 + /// Example: https://hatsu.local/users/example.com/collection?page=64 #[serde(skip_serializing_if = "Option::is_none")] last: Option<Url>, - // collection count + /// Collection count total_items: u64,This change will improve the generated documentation for the struct.
27-50
: LGTM: Well-implemented constructor with a minor suggestion.The
new
method is well-implemented, correctly initializing all fields of theCollection
struct. It handles the optionaltotal_pages
parameter appropriately and uses a helper function for generating page URLs.Consider simplifying the logic for setting the
last
field and handling the edge case whentotal_pages
isSome(0)
:pub fn new( collection_id: &Url, total_items: u64, total_pages: Option<u64>, ) -> Result<Self, AppError> { Ok(Self { kind: OrderedCollectionType::OrderedCollection, id: collection_id.clone(), first: generate_collection_page_url(collection_id, 1)?, - last: match total_pages { - Some(total_pages) => Some(generate_collection_page_url( - collection_id, - match total_pages { - page if total_pages > 0 => page + 1, - _ => 1, - }, - )?), - None => None, - }, + last: total_pages.filter(|&pages| pages > 0).map(|pages| generate_collection_page_url(collection_id, pages)).transpose()?, total_items, }) }This change simplifies the logic and ensures that
last
isNone
whentotal_pages
is 0 orNone
.crates/apub/src/collections/collection_page.rs (2)
9-28
: LGTM: Well-structuredCollectionPage<T>
definition with a minor suggestion.The
CollectionPage<T>
struct is well-designed and properly annotated for serialization and OpenAPI documentation. The use of generics allows for flexibility in the type of items stored in the collection.Consider adding doc comments (
///
) to the struct and its fields to provide more detailed documentation. This will enhance the generated API documentation and improve code readability. For example:/// Represents a page of an ordered collection. #[derive(Clone, Debug, Deserialize, Serialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct CollectionPage<T> { /// The type of the collection page. #[serde(rename = "type")] kind: OrderedCollectionPageType, /// The URL of the current page. id: Url, // ... (add similar comments for other fields) }
30-57
: LGTM: Solid implementation with minor suggestions for improvement.The
new
method forCollectionPage<T>
is well-implemented, handling pagination logic correctly and using proper error handling withResult<Self, AppError>
.Consider the following improvements:
- Replace the Chinese comments with English for better accessibility:
// Provide previous page if current page is greater than 1 prev: match page { page if page > 1 => Some(generate_collection_page_url(&collection_id, page - 1)?), _ => None, }, // Provide next page if current page is less than total pages next: match page { page if page < total_pages => Some(generate_collection_page_url(&collection_id, page + 1)?), _ => None, },
- Add doc comments to the
new
method to describe its parameters and return value:/// Creates a new `CollectionPage<T>` instance. /// /// # Arguments /// /// * `collection_id` - The URL of the entire collection. /// * `total_items` - The total number of items in the collection. /// * `ordered_items` - The items in the current page. /// * `total_pages` - The total number of pages in the collection. /// * `page` - The current page number. /// /// # Returns /// /// A `Result` containing the new `CollectionPage<T>` instance or an `AppError`. pub fn new( collection_id: Url, total_items: u64, ordered_items: Vec<T>, total_pages: u64, page: u64, ) -> Result<Self, AppError> { // ... (existing implementation) }These changes will improve code readability and documentation.
crates/api_apub/src/users/user_following.rs (1)
Incorrect redirect URL in
user_following.rs
The
redirect
function currently points to/users/{name}/followers
, but it should point to/users/{name}/following
to maintain consistency with the file's purpose.🔗 Analysis chain
Line range hint
61-63
: Verify the correctness of the redirect URLThe
redirect
function redirects to/users/{name}/followers
, but since this file handles the following endpoint, should the redirect point to/users/{name}/following
instead? Please verify whether this is intentional or if it should be corrected to ensure consistency.To confirm if the redirect URL is correct, you can search for usages of the
redirect
function and check the intended redirect paths:🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the redirect URL in the `redirect` function. # Test: Search for the `redirect` function definition and its usage. rg --type rust 'pub async fn redirect' -A 3 # Test: Check for routes or handlers that might be invoking this redirect. rg --type rust 'redirect::\(.*\)' # Expected Result: Ensure that the redirect points to the appropriate URL based on the context.Length of output: 1904
Script:
#!/bin/bash # Description: Extract redirect URLs from user_following.rs and verify correctness. # Extract the redirect URL from user_following.rs rg --type rust 'pub async fn redirect' crates/api_apub/src/users/user_following.rs -A 2 # Extract all redirect URLs related to user_following to verify consistency rg --type rust 'Redirect::permanent' crates/api_apub/src/users/user_following.rsLength of output: 356
crates/api_apub/src/users/user_followers.rs (3)
33-33
: Clarify the parameter description foruser
The description
"The Domain of the User in the database."
may be misleading ifuser
represents the username or user ID. Consider updating the description to accurately reflect the nature of theuser
parameter.
Line range hint
49-49
: Address the TODO: Implement ordering bylast_refreshed_at
The code currently orders followers by
received_follow::Column::Id
. Implementing ordering bylast_refreshed_at
as indicated in the TODO comment will enhance the relevance of the followers list by displaying the most recently updated followers first.Would you like assistance in updating the ordering to use
last_refreshed_at
? I can help provide the code to implement this feature.
Line range hint
66-71
: Potential logical error in page validation conditionThe condition
if page > 1 && page > total.number_of_pages
might not correctly handle invalid page numbers less than 1. Consider modifying the condition toif page < 1 || page > total.number_of_pages
to catch all invalid page numbers and prevent potential errors.Apply this diff to correct the condition:
-if page > 1 && page > total.number_of_pages { +if page < 1 || page > total.number_of_pages {crates/api_apub/src/users/user_outbox.rs (3)
34-34
: Clarify the description of theuser
parameterThe description for the
user
parameter states: "The Domain of the User in the database." Sinceuser
represents the username or identifier, consider updating the description to accurately reflect this. For example:-("user" = String, Path, description = "The Domain of the User in the database."), +("user" = String, Path, description = "The username or identifier of the user."),
Line range hint
51-51
: Address the TODO: Order activities bylast_refreshed_at
There's a TODO comment indicating the need to order activities by
last_refreshed_at
. Implementing this will ensure that the outbox displays the most recently updated activities first, improving the user experience.Would you like assistance in implementing this feature, or should a new GitHub issue be created to track this task?
Line range hint
83-89
: Handle errors fromactivity.into_json()
explicitlyUsing
filter_map(Result::ok)
ignores any errors returned byactivity.into_json()
, potentially causing silent data loss if an activity fails to convert. Consider handling errors explicitly to ensure that any issues are logged or communicated appropriately.Apply this diff to handle errors explicitly:
.map(|activity| { let activity: ApubActivity = activity.into(); - activity.into_json() + match activity.into_json() { + Ok(json) => Some(json), + Err(err) => { + // Log the error or handle it accordingly + eprintln!("Error converting activity to JSON: {:?}", err); + None + } + } }) -.filter_map(Result::ok) .filter_map(|json| json) .collect(),Alternatively, you could collect the errors and decide on a strategy, such as failing the request or returning partial results with warnings.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (12)
- crates/api_apub/src/lib.rs (2 hunks)
- crates/api_apub/src/posts/mod.rs (1 hunks)
- crates/api_apub/src/posts/notice.rs (1 hunks)
- crates/api_apub/src/users/mod.rs (2 hunks)
- crates/api_apub/src/users/user_followers.rs (4 hunks)
- crates/api_apub/src/users/user_following.rs (1 hunks)
- crates/api_apub/src/users/user_inbox.rs (1 hunks)
- crates/api_apub/src/users/user_outbox.rs (4 hunks)
- crates/apub/src/collections/collection.rs (1 hunks)
- crates/apub/src/collections/collection_page.rs (1 hunks)
- crates/apub/src/collections/mod.rs (2 hunks)
- crates/backend/src/openapi.rs (1 hunks)
🔇 Additional comments (17)
crates/api_apub/src/posts/mod.rs (2)
Line range hint
1-16
: Clarify status of Utoipa documentation task.The AI summary mentions that a comment about writing Utoipa documentation has been removed. Could you please clarify:
- Has the task of writing Utoipa documentation been completed?
- If not, is there a plan or timeline for completing this task?
- If it's no longer relevant, why was it decided to remove the documentation task?
This information will help ensure that the PR objectives are fully met and that the API documentation is complete.
To help verify the status of the Utoipa documentation, please run the following script:
#!/bin/bash # Description: Check for Utoipa documentation in relevant files # Test: Look for Utoipa path attributes in the posts directory rg --type rust '#\[utoipa::path' crates/api_apub/src/posts # Test: Check for any TODO comments related to documentation rg --type rust 'TODO.*document' crates/api_apub/src/postsPlease review the output to confirm the current state of the Utoipa documentation in the relevant files.
7-7
: Approved: Module visibility change enhances API documentation.The
notice
module is now public, which aligns with the PR objective of updating OpenAPI documentation. This change allows the module to be referenced in the API docs, potentially improving their completeness and accuracy.To ensure this change doesn't unintentionally expose internal implementation details, please run the following script:
Please review the output to confirm that only intended elements are exposed and properly documented.
✅ Verification successful
Verified:
notice
module visibility change is appropriate and does not expose unintended elements.The
notice
module is now public without exposing any public functions, structs, enums, or traits. This change aligns with the PR objective of updating OpenAPI documentation and ensures that no internal implementation details are inadvertently exposed.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for any new public exports in the notice module # that might need additional documentation or security review. # Test: Look for public declarations in the notice module rg --type rust '^\s*pub\s' crates/api_apub/src/posts/notice.rs # Test: Check if the notice module is imported in other parts of the codebase rg --type rust 'use .*posts::notice' -g '!crates/api_apub/src/posts/mod.rs'Length of output: 399
Script:
#!/bin/bash # Description: List all public items in the notice module to ensure only intended elements are exposed. # List public functions rg --type rust 'pub fn' crates/api_apub/src/posts/notice.rs # List public structs, enums, and other items rg --type rust 'pub (struct|enum|trait)' crates/api_apub/src/posts/notice.rs # Check for documentation comments on public items rg --type rust 'pub .*?\n\s*///' crates/api_apub/src/posts/notice.rsLength of output: 403
Script:
#!/bin/bash # Description: List all public items in the notice module to ensure only intended elements are exposed. # List public functions rg --type rust 'pub fn' crates/api_apub/src/posts/notice.rs # List public structs, enums, and traits rg --type rust 'pub (struct|enum|trait)' crates/api_apub/src/posts/notice.rs # Check for documentation comments on public items with multiline mode enabled rg --type rust -U 'pub .*?\n\s*///' crates/api_apub/src/posts/notice.rsLength of output: 214
crates/api_apub/src/posts/notice.rs (2)
4-4
: LGTM: TAG import added.The import of the
TAG
constant from the crate root is appropriate. This constant is likely used for categorizing API endpoints, which aligns with the OpenAPI documentation practices.
Line range hint
1-31
: Summary: Excellent implementation of the notice endpoint with comprehensive OpenAPI documentation.This new endpoint successfully addresses the PR objectives by providing a well-documented and implemented route for retrieving posts by base64-encoded URL. The OpenAPI documentation is thorough, and the implementation includes proper error handling and security checks. The use of
base64_simd
demonstrates attention to performance.A few minor suggestions have been made to further improve the code:
- Adding a summary to the OpenAPI documentation for quick understanding.
- Refactoring the error handling for more specific error messages.
Overall, this is a high-quality addition to the API that aligns well with the project's goals.
crates/api_apub/src/users/mod.rs (1)
2-2
: LGTM: Import statement forDeserialize
added.The addition of
use serde::Deserialize;
is appropriate for the newPagination
struct.crates/api_apub/src/lib.rs (5)
3-3
: LGTM: Import additions are appropriate.The new imports for
Collection
,CollectionOrPage
,CollectionPage
,Value
, andUrl
are necessary for the OpenAPI component additions and align with the PR objective of updating the documentation.Also applies to: 7-8
Line range hint
1-53
: LGTM: Overall structure and consistency maintained.The changes to this file maintain the existing structure while effectively expanding the API documentation. The additions are consistent with the PR objectives and enhance the overall API capabilities.
Line range hint
1-53
: Great job: Changes align well with PR objectives.The modifications in this file successfully address the PR objective of updating the OpenAPI documentation for the
apub
module. The additions of new paths and components related to posts align with the requirements outlined in issue #66.As a final verification step, please run the following script to ensure all required routes are properly documented:
#!/bin/bash # Description: Verify that all routes in the `posts` module are documented in the OpenAPI specification # Test: List all route definitions in the posts module routes=$(rg --type rust -e 'pub fn' crates/api_apub/src/posts | awk '{print $3}' | cut -d'(' -f1) # Test: Check if each route is included in the OpenAPI specification for route in $routes; do if ! grep -q "$route" crates/api_apub/src/lib.rs; then echo "Warning: Route $route is not documented in the OpenAPI specification" fi doneThis script will help ensure that all implemented routes in the
posts
module are properly documented in the OpenAPI specification.
29-32
: LGTM: New components added to OpenAPI specification.The addition of
Collection
,CollectionOrPage
,CollectionPage<Url>
, andCollectionPage<Value>
components aligns with the PR objective and corresponds to the newly imported types.To ensure the completeness of the schema definitions, please run the following script:
#!/bin/bash # Description: Verify the schema definitions for the new components # Test: Check if the new components have proper schema definitions rg --type rust -e 'struct Collection' -e 'struct CollectionOrPage' -e 'struct CollectionPage' crates/api_apub/src # Test: Check if the new components are properly documented with utoipa attributes rg --type rust -e '#\[derive\(.*Schema.*\)\]' -A 10 -e 'struct Collection' -e 'struct CollectionOrPage' -e 'struct CollectionPage' crates/api_apub/src
20-23
: LGTM: New paths added to OpenAPI specification.The addition of
posts::notice::notice
andposts::post::post
paths aligns with the PR objective of updating the OpenAPI documentation for theapub
module.To ensure the completeness of the implementation, please run the following script:
crates/apub/src/collections/collection.rs (2)
1-7
: LGTM: Imports are well-organized and relevant.The imports cover all necessary dependencies for the implementation, including ActivityPub federation, error handling, serialization, URL handling, and OpenAPI documentation. They follow Rust conventions and are organized logically.
1-50
: Overall: Excellent implementation aligning with PR objectives.This new file introduces a well-structured
Collection
struct for ActivityPub implementation, which aligns perfectly with the PR objectives of updating OpenAPI documentation for theapub
module. The code is clean, well-organized, and follows Rust best practices.Key strengths:
- Proper use of derive macros and serde attributes for serialization and documentation.
- Well-implemented constructor method with error handling.
- Clear structure that contributes to the goal of documenting the
apub
module.The minor suggestions provided earlier will further enhance the code quality and documentation. Great job on this implementation!
crates/apub/src/collections/collection_page.rs (2)
1-8
: LGTM: Imports are appropriate and well-organized.The imports cover all necessary dependencies for implementing the
CollectionPage
struct and its functionality. The use of the internalgenerate_collection_page_url
function from the parent module is a good practice for code organization.
1-57
: Overall assessment: Well-implementedCollectionPage<T>
with good alignment to PR objectives.This new file introduces a robust
CollectionPage<T>
struct that aligns well with the PR objectives of updating OpenAPI documentation. The implementation provides a solid foundation for handling paginated collections in the API, which is crucial for efficient data retrieval and presentation.Key strengths:
- Proper use of generics for flexibility.
- Correct handling of pagination logic.
- Good error handling with
Result<Self, AppError>
.- Appropriate use of serde attributes for JSON serialization.
The suggested improvements (adding doc comments and translating Chinese comments) will further enhance the code quality and documentation. Overall, this addition significantly contributes to the goal of improving the API documentation and functionality.
crates/api_apub/src/users/user_following.rs (3)
17-30
: OpenAPI documentation updated to reflect new response type and parametersThe
#[utoipa::path]
attribute has been correctly updated to document the endpoint with the newCollectionOrPage
response type and includes thePagination
parameters. This ensures that the OpenAPI documentation accurately represents the API's current behavior.
34-34
: Simplify handler function by acceptingQuery<Pagination>
directlyChanging the handler to accept
Query<Pagination>
instead of anOption<Query<Pagination>>
simplifies the code by removing unnecessary option wrapping. SincePagination
can handle optional page parameters internally, this change makes the handler cleaner and easier to maintain.
36-36
: Update return type to reflect new response structureUpdating the return type to
Result<FederationJson<WithContext<CollectionOrPage>>, AppError>
correctly reflects the new response types being returned by the handler. This ensures type safety and clarity in the function signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (3)
crates/apub/tests/collections_local.rs (3)
1-8
: Consider implementing tests for CollectionPageThere's a TODO comment indicating that tests for
CollectionPage
are planned. It would be beneficial to implement these tests to ensure comprehensive coverage of thecollections
module.Would you like assistance in creating test cases for
CollectionPage
? I can help draft some test scenarios or open a GitHub issue to track this task.
9-21
: LGTM! Consider parameterizing the test for better coverage.The
new_collection
test effectively verifies the creation of aCollection
instance and checks the correctness of thefirst
andlast
URLs. Good job on covering this functionality!To enhance the test's robustness, consider parameterizing it with different input values. This approach would allow testing various scenarios without duplicating code. Here's an example of how you could refactor the test:
use rstest::rstest; #[rstest] #[case(100, 10, "https://hatsu.local/collections/test1?page=1", "https://hatsu.local/collections/test1?page=10")] #[case(50, 5, "https://hatsu.local/collections/test1?page=1", "https://hatsu.local/collections/test1?page=10")] #[case(9, 10, "https://hatsu.local/collections/test1?page=1", "https://hatsu.local/collections/test1?page=1")] fn test_new_collection( #[case] total_items: usize, #[case] items_per_page: usize, #[case] expected_first: &str, #[case] expected_last: &str ) -> Result<(), AppError> { let collection_id = Url::parse("https://hatsu.local/collections/test1")?; let collection = Collection::new(&collection_id, total_items, items_per_page)?; assert_eq!(collection.first, Url::parse(expected_first)?); assert_eq!(collection.last, Url::parse(expected_last)?); Ok(()) }This approach uses the
rstest
crate to provide multiple test cases, increasing coverage and making the test more flexible.
23-34
: LGTM! Consider adding an assertion for total items.The
new_empty_collection
test effectively verifies the creation of an emptyCollection
instance and checks that bothfirst
andlast
URLs point to the same page. This is a good test for the edge case of an empty collection.To make the test even more robust, consider adding an assertion to verify that the
total_items
field of theCollection
is indeed 0. This would ensure that theCollection::new
method correctly sets this field for empty collections. Here's an example of how you could add this assertion:#[test] fn new_empty_collection() -> Result<(), AppError> { let collection_id = Url::parse("https://hatsu.local/collections/test2")?; let collection = Collection::new(&collection_id, 0, 0)?; let expected_url = Url::parse("https://hatsu.local/collections/test2?page=1")?; assert_eq!(collection.first, expected_url); assert_eq!(collection.last, expected_url); assert_eq!(collection.total_items, 0); Ok(()) }This additional assertion would provide extra confidence in the correctness of the
Collection::new
method for empty collections.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (5)
- crates/api_apub/src/users/user_followers.rs (4 hunks)
- crates/api_apub/src/users/user_following.rs (1 hunks)
- crates/api_apub/src/users/user_outbox.rs (4 hunks)
- crates/apub/src/collections/collection.rs (1 hunks)
- crates/apub/tests/collections_local.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- crates/api_apub/src/users/user_followers.rs
- crates/api_apub/src/users/user_following.rs
- crates/api_apub/src/users/user_outbox.rs
- crates/apub/src/collections/collection.rs
🔇 Additional comments (1)
crates/apub/tests/collections_local.rs (1)
1-34
: Good test coverage, consider expanding for comprehensive testingOverall, this test file provides good coverage for the basic functionality of the
Collection
struct. The two tests effectively verify the creation of both non-empty and empty collections, which are important scenarios to cover.To further improve the test suite, consider the following suggestions:
- Implement tests for the
CollectionPage
struct as mentioned in the TODO comment.- Parameterize the
new_collection
test to cover more scenarios with different input values.- Add assertions to verify other properties of the
Collection
struct, such astotal_items
anditems_per_page
.- Consider adding tests for edge cases or potential error scenarios, such as creating a collection with invalid URLs or inconsistent pagination parameters.
These improvements would enhance the robustness and completeness of your test suite, providing better confidence in the correctness of the
collections
module.
fix #66
Summary by CodeRabbit
Release Notes
New Features
Improvements
Bug Fixes