Skip to content

Client call with named params#541

Merged
tomusdrw merged 26 commits into
paritytech:masterfrom
willemolding:client-call-with-named-params
Mar 23, 2020
Merged

Client call with named params#541
tomusdrw merged 26 commits into
paritytech:masterfrom
willemolding:client-call-with-named-params

Conversation

@willemolding
Copy link
Copy Markdown
Contributor

@willemolding willemolding commented Feb 18, 2020

Add named_params option to RPC derive macro

Closes #540

While the server generated by the derive macro doesn't support calling functions with named params some other systems do (some exclusively). It would still be nice to use the clean derive macro syntax to generate a client in this case.

This PR adds a flag named_params to the rpc method attribute. Example:

#[rpc(name = "add", named_params)]
fn add(&self, a: u32, b: u32) -> Result<String>;

In this case the json-rpc call object produced by calling the generated method on a client will have a params object that takes the key names from the function parameter names.

{
   "jsonrpc": "2.0",
   "params": {"a": 4, "b": 2},
   ...
}

As the server doesn't support this it is important that this cannot be used when deriving server RPC methods. The rpc derive macro will throw a compile time error if the named_params switch is used in any case other than #[rpc(client)]. See (derive/tests/ui/attr-named-params-on-server.rs)

@parity-cla-bot
Copy link
Copy Markdown

It looks like @willemolding hasn't signed our Contributor License Agreement, yet.

The purpose of a CLA is to ensure that the guardian of a project's outputs has the necessary ownership or grants of rights over all contributions to allow them to distribute under the chosen licence.
Wikipedia

You can read and sign our full Contributor License Agreement at the following URL: https://cla.parity.io

Once you've signed, please reply to this thread with [clabot:check] to prove it.

Many thanks,

Parity Technologies CLA Bot

@willemolding
Copy link
Copy Markdown
Contributor Author

[clabot:check]

@parity-cla-bot
Copy link
Copy Markdown

It looks like @willemolding signed our Contributor License Agreement. 👍

Many thanks,

Parity Technologies CLA Bot

Comment thread derive/tests/client.rs Outdated

#[rpc(client)]
pub trait Rpc {
#[rpc(name = "call_with_named", named_params)]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it make sense to specify named_params in the trait level attribute instead? On the one hand it's good to have the fine grained control - but in practice wouldn't all methods be either named or positional?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We already have raw_params on the method level. I think this is a good idea to have it here, but an additional attribute on the trait level would be cool tool, especially in the future if we implement server side as well.

Copy link
Copy Markdown
Contributor

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

Nice! Looks good to me. Please let us know what you think about @ascjones suggestion about the trait-level attribute.

Comment thread derive/tests/client.rs Outdated

#[rpc(client)]
pub trait Rpc {
#[rpc(name = "call_with_named", named_params)]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We already have raw_params on the method level. I think this is a good idea to have it here, but an additional attribute on the trait level would be cool tool, especially in the future if we implement server side as well.

@willemolding
Copy link
Copy Markdown
Contributor Author

I like the idea of having it at the trait level to set the default, which can then be overridden at the method level. That way we have the fined grained control as well. I'm picturing something like

#[rpc(client, params = "named")] // sets the default to named params
pub trait Rpc {
	#[rpc(name = "call_with_named")] // uses the trait default
        fn call_with_named() -> {
        ...
        #[rpc(name = "call_positional", params = "positional")] // overrides trait default
        fn call_positional() -> {
}

@tomusdrw
Copy link
Copy Markdown
Contributor

tomusdrw commented Feb 21, 2020

That looks really nice, are you willing to change how raw_params work as well? I imagine that params would take any of "raw"|"positional"|"named".

I guess we would need to keep raw_params for one version and mark it deprecated (i.e produce a warning if used).

@willemolding
Copy link
Copy Markdown
Contributor Author

Ok getting pretty close.

There are now three options for params: ["named", "positional", "raw"]. You can also use the old raw_params flag which overrides the setting but I couldn't figure out how to trigger a compiler warning.

This can be set at the trait level (which then becomes the default for all trait methods without a params attribute key. It can also be used at the method level which overrides the default from the trait so both calling type can be used together.

I'm done for today but I would appreciate suggestions for any more tests this might need to be sure it is solid

Comment thread derive/src/rpc_attr.rs Outdated
Copy link
Copy Markdown
Contributor

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

Looks good, few minor things.

Comment thread derive/src/options.rs Outdated
Comment thread derive/src/options.rs Outdated
Comment thread derive/src/rpc_attr.rs Outdated
let raw_params =
get_meta_list(meta).map_or(false, |ml| has_meta_word(RAW_PARAMS_META_WORD, ml));
let params_style = match raw_params {
true => Ok(Some(ParamStyle::Raw)),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we print a deprecation warning here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately I can't figure out a way to emit a warning without using the proc_macro::Diagnostic feature which is unstable

Not sure if we have any other ideas for this or if it is ok to just add a depreciation note to the docs but not the macro

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think in the past we simply used to println the warning. @ascjones do you recall?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes we did use a simple println IIRC

Comment thread derive/src/rpc_trait.rs Outdated
Comment thread derive/src/to_delegate.rs
Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
@willemolding
Copy link
Copy Markdown
Contributor Author

Thanks for the review @tomusdrw. The only thing lacking is a deprecation warning for using the now-deprecated raw_params flag. Not sure if anyone knows a trick for this or are we happy to just have the updated docs showing the new way?

Copy link
Copy Markdown
Contributor

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

Looks good to me! I think deprecation warning (via println if works) would be nice, but is not critical.

Comment thread derive/src/rpc_attr.rs Outdated
let raw_params =
get_meta_list(meta).map_or(false, |ml| has_meta_word(RAW_PARAMS_META_WORD, ml));
let params_style = match raw_params {
true => Ok(Some(ParamStyle::Raw)),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think in the past we simply used to println the warning. @ascjones do you recall?

Copy link
Copy Markdown
Contributor

@ascjones ascjones left a comment

Choose a reason for hiding this comment

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

LGTM

Comment thread derive/src/rpc_attr.rs Outdated
let raw_params =
get_meta_list(meta).map_or(false, |ml| has_meta_word(RAW_PARAMS_META_WORD, ml));
let params_style = match raw_params {
true => Ok(Some(ParamStyle::Raw)),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes we did use a simple println IIRC

@willemolding
Copy link
Copy Markdown
Contributor Author

It looks like using println! won't make a compile time error/warning. It would be a matter of making the generated code contain a runtime println! which seems wrong to me.

I left a placeholder warning so if/when the proc-macro diagnostics becomes stable it will be simple to add it in.

Copy link
Copy Markdown
Contributor

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

Fair enough, looks good to merge then.

Could you take a look at the CI failure?
image

@tomusdrw
Copy link
Copy Markdown
Contributor

tomusdrw commented Mar 5, 2020

Apparently it seems to be upstream issue, could you fix the quote version like here? paritytech/substrate#5135

@willemolding
Copy link
Copy Markdown
Contributor Author

Apparently it seems to be upstream issue, could you fix the quote version like here? paritytech/substrate#5135

Hmm this doesn't seem to have fixed it. It sure is a pain not being able to see the CI output

@tomusdrw
Copy link
Copy Markdown
Contributor

Hmm this doesn't seem to have fixed it. It sure is a pain not being able to see the CI output

Yeah, sorry about that. Seems that 1.0.2 is yanked. Could you roll back to =1.0.1? I tested that locally and it should work.

@tomusdrw
Copy link
Copy Markdown
Contributor

Thanks!

@tomusdrw tomusdrw merged commit c64a48a into paritytech:master Mar 23, 2020
@ascjones ascjones mentioned this pull request Apr 14, 2020
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.

Support for by-name parameters in #[rpc(client)] macro

4 participants