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

Add the resource to client requests when using the Resources Plugin. #4747

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

MarcusDunn
Copy link
Contributor

@MarcusDunn MarcusDunn commented Mar 21, 2025

Subsystem
Client, Resources

Motivation
This PR allows downstream plugins to introspect the resource used to create the request URL.

The motivating use case for this is to allow spans to be named GET api/user/{id}?query={query} instead of GET, which is the best downstream telemetry can do right now.

This would result in a huge quality of life improvement around aggregating client requests to the same endpoint. Currently I'm writing regex against the full URL which is both slow, error prone and has to be done for each endpoint.

Solution
I've added a RESOURCE attribute to the request when the resources plugin is used.

I've made a seperate PR to opentelemetry-java-instrumentation to use this attribute to populate url.template open-telemetry/opentelemetry-java-instrumentation#13572

I will make a PR to opentelemetry-java-instrumentation once this is merged so I can test on that side. (as requested by their maintainers)

Alternatives

  • Don't do anything. This is out of scope of KTOR. Application should be handling things like this.

Copy link

coderabbitai bot commented Mar 21, 2025

Walkthrough

The pull request introduces enhancements to the ktor-client-resources plugin, focusing on resource attribute handling within the HttpClient class. Key changes include the addition of a public property RESOURCE for storing resource instances and modifications to various HTTP methods to ensure these resources are accessible during requests. Additionally, a new resource class PathWithOptionalQueryParameter is introduced in the test suite, along with a new test method to verify the correct association of URL templates as attributes during requests.

Changes

File(s) Change Summary
ktor-client/.../builders.kt Added new public property RESOURCE: AttributeKey<Any> for resource instance storage. Updated HTTP methods to store resource instances in attributes using attributes.put(RESOURCE, resource).
ktor-client/.../ResourcesTest.kt Introduced resource class PathWithOptionalQueryParameter(val id: Int, val query: String? = null) and added test method fun check template is added as attribute() to verify URL template generation and attribute association.

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8cd1665 and f6fe069.

📒 Files selected for processing (2)
  • ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt (17 hunks)
  • ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt
🧰 Additional context used
🧬 Code Graph Analysis (1)
ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (3)
ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngine.kt (1)
  • config (20-108)
ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockEngineConfig.kt (1)
  • addHandler (55-57)
ktor-client/ktor-client-mock/common/src/io/ktor/client/engine/mock/MockUtils.kt (1)
  • respondOk (67-69)
🔇 Additional comments (3)
ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (3)

6-6: Added necessary imports for the new test case.

These imports (createClientPlugin and assertSame) are required for the new test case that verifies resource attributes.

Also applies to: 16-16


155-156: Well-structured resource class for testing.

The PathWithOptionalQueryParameter class effectively models a resource with a required path parameter and an optional query parameter, which is suitable for testing the new resource attribute functionality.


158-183: Good test implementation for verifying resource attribute handling.

This test properly verifies that the resource instance is correctly attached to the request attributes via the RESOURCE key. The test:

  1. Creates a specific resource instance
  2. Uses a custom plugin to assert that the same resource instance is accessible from request attributes
  3. Confirms the request completes successfully

This directly addresses the PR objective of enhancing downstream plugin capabilities by making the resource template available for introspection.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a8b186 and 9b1bac2.

📒 Files selected for processing (2)
  • ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt (17 hunks)
  • ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (2 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (1)
ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt (1) (1)
  • urlTemplate (314-333)
🔇 Additional comments (12)
ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (9)

156-157: Good resource definition for testing optional query parameters.

The new PathWithOptionalQueryParameter class is well structured with a required id parameter and an optional query parameter, which is perfect for testing the URL template generation with optional query parameters.


159-183: Test verifies URL template attribute is correctly added.

This test effectively verifies that the URL_TEMPLATE attribute is correctly set during requests with resources. The approach of using a client plugin to assert the attribute value is a clean way to validate the functionality.


185-191: Good test for URL template generation with required parameters.

This test ensures that the URL template correctly generates the expected format for resources with multiple required parameters, properly handling the path structure and query parameters.


193-199: Test ensures optional query parameters are correctly marked in templates.

This test confirms that optional query parameters (marked with nullable types or default values) are correctly represented in the URL template with a ? suffix, which aligns with the PR objectives.


6-6: Appropriate imports added for new functionality.

The imports for createClientPlugin, ResourcesFormat, and serializer are correctly added to support the new URL template functionality being tested.

Also applies to: 14-15


156-157: Well-designed test resource with optional parameter.

This resource class is properly defined with an optional query parameter, making it suitable for testing URL template generation with optional parameters. The design aligns well with the PR objective of supporting template URL attributes.


159-183: Good verification of URL template attributes.

This test effectively verifies that the URL template is correctly added as an attribute to the request when using the Resources plugin. The implementation properly:

  1. Sets up a test environment with the Resources plugin
  2. Creates a client plugin to assert the URL template matches the expected value
  3. Verifies the template is available via the URL_TEMPLATE attribute

This directly addresses the core goal of the PR to "add template URL attribute to client requests."


185-191: Good test for URL template generation with path and query parameters.

This test properly validates the urlTemplate function's output for a more complex resource type with nested path parameters and a list query parameter. The expected template format correctly follows the pattern described in the PR objectives.


193-199: Effective verification of optional query parameter handling.

This test confirms that optional query parameters are properly marked with a question mark in the URL template. The test case complements the previous one by specifically validating how optional parameters are denoted in the template.

This functionality is crucial for downstream plugins that will use these templates for request introspection and span naming.

ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt (3)

305-306: LGTM! Good definition of the URL template attribute key.

The URL_TEMPLATE attribute key is appropriately defined as a public constant, making it accessible to downstream plugins that need to read this information from requests.


307-312: Well-designed helper function for setting URL template attribute.

This function encapsulates the logic for generating and storing a URL template in the request attributes, providing a clean API for the HTTP method implementations to use.


314-333: URL template generation function handles both path and query parameters appropriately.

The urlTemplate function correctly builds the URL template by combining:

  1. The path pattern from the resource format
  2. Query parameters with proper formatting for required and optional parameters

The handling of optional parameters with the ? suffix aligns with common template syntax conventions and ensures downstream plugins can properly understand the template structure.

@MarcusDunn MarcusDunn force-pushed the ad-template-to-request branch from 3fdc376 to 881f666 Compare April 6, 2025 19:35
@MarcusDunn MarcusDunn changed the title Add template URL attribute to client requests when using the Resources Plugin. Add the resource to client requests when using the Resources Plugin. Apr 6, 2025
Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (1)
ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt (1)

305-309: Fix minor grammatical error in documentation

There's a small grammatical error in the documentation for the RESOURCE attribute.

-/**
- * The instance of the [Resource] annotated class used to for a request.
- * Plugins may want to utilize this for monitoring.
- */
+/**
+ * The instance of the [Resource] annotated class used for a request.
+ * Plugins may want to utilize this for monitoring.
+ */
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 881f666 and 99e954e.

📒 Files selected for processing (2)
  • ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt (17 hunks)
  • ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (3 hunks)
🔇 Additional comments (5)
ktor-client/ktor-client-plugins/ktor-client-resources/common/src/io/ktor/client/plugins/resources/builders.kt (2)

12-14: Good addition of necessary imports

These imports are correctly added to support the new functionality for storing resource instances as attributes in HTTP requests.


44-44: Well-implemented attribute storage across all HTTP methods

The consistent addition of attributes.put(RESOURCE, resource) across all HTTP methods ensures that the resource instance is always accessible during request execution. This implementation aligns perfectly with the PR objective to enhance introspection capabilities.

Also applies to: 61-61, 78-78, 95-95, 112-112, 129-129, 146-146, 163-163, 180-180, 197-197, 214-214, 231-231, 248-248, 265-265, 282-282, 299-299

ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (3)

6-6: Appropriate imports added

The imports for createClientPlugin and assertSame are correctly added to support the new test functionality.

Also applies to: 16-16


155-156: Well-defined test resource class

This resource class is well-designed for testing the URL template attribute functionality, with an ID parameter in the path and an optional query parameter.


158-181: Comprehensive test for resource attribute storage

The test effectively verifies that the resource instance is correctly stored in the request attributes. The use of assertSame ensures object identity is maintained, and the client plugin approach elegantly hooks into the request pipeline for verification.

This test is aligned with the PR objective of enhancing the introspection capabilities for downstream plugins.

Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (1)
ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (1)

159-183: Good test implementation for RESOURCE attribute verification.

This test effectively verifies the PR's main objective: ensuring that resource instances are correctly associated with request attributes. The test:

  1. Creates a resource instance
  2. Uses a custom plugin to verify the resource is stored in the request attributes
  3. Confirms the request completes successfully

The use of assertSame is appropriate for verifying object identity rather than just equality.

For better documentation, consider adding a comment explaining that this test verifies the behavior introduced by the RESOURCE attribute key for tracking template resources in requests.

 @Test
-fun `check template is added as attribute`() = testWithEngine(MockEngine) {
+/**
+ * Verifies that the resource instance is correctly associated with the request 
+ * attributes via the RESOURCE attribute key, which enables downstream plugins 
+ * to introspect the template used for creating request URLs.
+ */
+fun `check template is added as attribute`() = testWithEngine(MockEngine) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c1834f and 54a01a1.

📒 Files selected for processing (1)
  • ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (3 hunks)
🔇 Additional comments (2)
ktor-client/ktor-client-plugins/ktor-client-resources/common/test/ResourcesTest.kt (2)

6-6: Good addition of necessary imports.

The imports for createClientPlugin and assertSame are correctly added to support the new test functionality.

Also applies to: 16-16


155-157: Well-structured resource class definition.

The PathWithOptionalQueryParameter class is cleanly defined with an appropriate path template and properly typed parameters. The optional query parameter with a default value of null is a good choice for testing the attribute functionality.

@MarcusDunn MarcusDunn force-pushed the ad-template-to-request branch from 54a01a1 to 8cd1665 Compare April 7, 2025 15:39
@MarcusDunn MarcusDunn force-pushed the ad-template-to-request branch from 8cd1665 to f6fe069 Compare April 11, 2025 03:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant