heavy-duty / znap

Performance-first Rust Framework to build APIs compatible with the Solana Actions Spec.
Apache License 2.0
60 stars 1 forks source link

Custom, Prefix and Shorthand Path #87

Closed SergioRibera closed 1 month ago

SergioRibera commented 1 month ago

this close #45 close #55 and close #61

The following situations were added

// Case 2: with prefix // Path generated: /v1/my_super_app/send_donation

[action(

prefix = "v1",
custom_path = "{{prefix}}/my_super_app/{{action_name}}",

)] pub struct SendDonationAction;

// Case 3: no replacement // Path generated: /v1/my_super_app

[action(

prefix = "v1",
custom_path = "my_super_app",

)] pub struct SendDonationAction;

- Shorthand syntax for Action Links: In this case it is simple when the beginning of the href does not match the generated path then add it.
```rs
// Case 1: example of normal use
// href generated: /v1/send_donation?amount=5 
#[action(
    prefix = "v1",
    link = {
        label = "Send 5 SOL",
        href = "?amount=5",
    },
)]
pub struct SendDonationAction;

// Case 2: misuse, but expected behavior
// href generated: /v1/send_donation/api/send_donation?amount=5 
#[action(
    prefix = "v1",
    link = {
        label = "Send 5 SOL",
        href = "/api/send_donation?amount=5",
    },
)]
pub struct SendDonationAction;
danmt commented 1 month ago

I really love this PR, I feel like these were all easy wins that will greatly improve DX.

From reading the description provided, specially this part:

  • Shorthand syntax for Action Links: In this case it is simple when the beginning of the href does not match the generated path then add it.
// Case 1: example of normal use
// href generated: /v1/send_donation?amount=5 
#[action(
    prefix = "v1",
    link = {
        label = "Send 5 SOL",
        href = "?amount=5",
    },
)]
pub struct SendDonationAction;

// Case 2: misuse, but expected behavior
// href generated: /v1/send_donation/api/send_donation?amount=5 
#[action(
    prefix = "v1",
    link = {
        label = "Send 5 SOL",
        href = "/api/send_donation?amount=5",
    },
)]
pub struct SendDonationAction;

Wouldn't the expected behavior here in Case 2 be an href /v1/api/send_donation?amount=5? My thinking process here is something like: Given that the URL starts with / we assume it's "absolute". If the value was api/send_donation?amount=5 then I'd expect it to generate an href like /v1/send_donation/api/send_donation?amount=5.

This could be worked around by a simple solution: Append the href to the base path when it doesn't start with / and use the exact path when the href starts with /.

Haven't thought of it in depth, there might be some edge cases with this approach, if you are aware of any just lmk. I feel the major drawback of the current approach is that actions that need to hit another server i.e. https://my-other-actions.com/v2/api/another-action, we end up with something like /v1/send_donation/https://my-other-actions.com/v2/api/another-action.

There should be a another rule that takes care of hrefs starting with a protocol (http/https specially)

danmt commented 1 month ago

I don't really like the name custom_path, I'd prefer something like path unless it breaks something or it's some sort of reserved name.