Open pmnoxx opened 2 years ago
I'd make this even more fine-grained: conceptually, jsonrpc
consists of two parts:
It's important to separate data type definitions into a separate crate. That way, if someone wants use the API using a different networking stack (eg, based on blocking IO), they get to re-use definitions of the JSON API iteslf, without brining in tokio and actix ecosystems.
I think the end state here is that we publish near_rpc_types
crate which:
1.0.142
, like serde)My suggested path there:
near-jsonrpc-primitives
crate as the one that would become near_rpc_types
near-jsonrpc-primitives
near-jsonrpc-primitives
nrpc_types
? The call site would be nrpc_types::Block
, etc)0.1
to crates.io1.0
with the commitment to not make 2.0
for at least couple of years. Also, from me personally: this is a hugely important bit of work which has multiplicative implications for both how effective are folks working at nearcore itself, as well as how robust is the ecosystem which builds on top of us. Kudos for spearheading the effort @pmnoxx !
cc @ChaoticTempest as one of the consures of RPC which cares a lot about Rust-level semver stability.
removing serde from near-primitives
@pmnoxx That might be not that clear of a win since actually some other projects might use and serialize those. Given that we publish near-primitives now with a 0.x semver-breaking releases, it is fine if we introduce breaking change since users will still be able to use whatever version they used before and rarely they actually need to upgrade near-primitives.
I think the end state here is that we publish near_rpc_types crate...
Well, near-jsonrpc-primitives
is exactly that crate, and indeed it should not depend on other nearcore crates by default and only optionally depend on nearcore crates to implement From
trait for those.
@miraclx FYI, I had a chat with @matklad and suggested that he collaborate with you on this near-jsonrpc-primitives refactoring. This has been on my radar for quite a while, and I feel we can make these small steps toward better granularity of nearcore project and finally get to the point where we are comfortable releasing near-jsonrpc-client-rs 1.0
Had a design discussion with @miraclx, the write up is here:
https://hackmd.io/WeCthH5LQqGrHiO1dxv6WA
The most important bit is next steps:
Serilialize/Deserialize
impls from near-primitivesNot that "remove nearcore dependencies from jsonrpc-primitives
" is not there -- we can do that later, after we just concentrate serialize impls there.
removing serde from near-primitives
@pmnoxx That might be not that clear of a win since actually some other projects might use and serialize those. Given that we publish near-primitives now with a 0.x semver-breaking releases, it is fine if we introduce breaking change since users will still be able to use whatever version they used before and rarely they actually need to upgrade near-primitives.
I think the end state here is that we publish near_rpc_types crate...
Well,
near-jsonrpc-primitives
is exactly that crate, and indeed it should not depend on other nearcore crates by default and only optionally depend on nearcore crates to implementFrom
trait for those.
To clarify, removing serde
from near-primitives
is not done for the purpose of improving compile time. As you noticed It's going to be needed to compile dependencies. However. those libraries use serde
just, because jsonrpc
needs them for purpose of doing message serialization
/deserialization
of rpc
queries and responses. Removing of serde::Serialize
/ serde::Deserialize
shows us that the types in those creates are not used by jsonrpc
anymore.
@matklad @frol @miraclx Ok, the part 1 is done. near-network
only uses serde
with test_features
, which doesn't happen in production. near-network-primitives
/ near-client-primitives
doesn't use serde
.
There may be some other crates that do.
Some extra observation about view types here: https://github.com/near/nearcore/pull/6068#discussion_r786613250. TL;DR at least one *View
type is stored in the database, which feels suspect:
Some extra observation about view types here: #6068 (comment). TL;DR at least one
*View
type is stored in the database, which feels suspect:
@matklad #4159 :(
This was not fully addressed, see https://github.com/near/nearcore/pull/6587#discussion_r876113324
Another approach we should consider is defining the API in language-agnostic way and generating Rust-side of the API from the spec, rather than defining the spec in terms of rust impl.
Here's a good example:
https://www.twilio.com/docs/openapi/generating-a-rust-client-for-twilios-api#setup
openapi-generator generate -g rust \
-i https://raw.githubusercontent.com/twilio/twilio-oai/main/spec/json/twilio_api_v2010.json \
-o twilio-rust \
This pulls language-agnostic JSON API spec from github and generates a bunch Rust structs with serde from it.
This is going to be very labor intensive (we'd have to write the API spec essentially from scratch, reverse-engineering from current Rust structs), but should give us (and 3rd party developers!!) the best results. This also probably won't be incremental with respect to tactical refactors suggested above, so, if we do want to pursue this approach at some point, it makes sense to start that today.
I am not familiar with the API specification languages landscape, so I can't vouch for openapi in particular, though I have to admit that the above one-command snippet looks great!
I ... don't really understand why we didn't cover openapi-like approaches in https://hackmd.io/WeCthH5LQqGrHiO1dxv6WA
OpenAPI gravitates towards REST-like APIs and it does not support sum-types (enums). We would need to redesign the API in order to make it OpenAPI-friendly (and developers-friendly as well), and while it has been a long-standing wish, we never had time to sit down and address it.
We should refactor the code to separate
jsonrpc
from rest of the code base.Steps 1: remove usage of serde from crates other than
jsonrpc
.serde
is used mainly forSerialize
/Deserialize
of messages.serde
is used in following creates, simply becausejsonrpc
needs to serialize to json, to read/write messages to network. By removingserde
from those crates, we will be one step closer to cleaningjsonrpc
serde
fromnear-primitives
(only usesserde
withtest_fetures
)Step 2:
jsonrpc
and cleanup api, make sure it contains all types used.See https://github.com/near/nearcore/pull/5428#pullrequestreview-813563252