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

[SDK Request] Rust SDK #69

Open
netthier opened this issue Nov 18, 2022 · 8 comments
Open

[SDK Request] Rust SDK #69

netthier opened this issue Nov 18, 2022 · 8 comments
Labels
rust-sdk Affects the Rust SDK sdk-request Request for a new SDK

Comments

@netthier
Copy link

Hello, I'd like to request you to consider adding an official SDK for the Rust language.
The openapi-generator supports Rust and generally generates sane code (including async support if the reqwest client is chosen).

@rhamzeh rhamzeh added rust-sdk Affects the Rust SDK sdk-request Request for a new SDK labels Nov 18, 2022
@liamwh
Copy link

liamwh commented Mar 26, 2024

+1. I heard Andres Aguiar mention on the 25th of October last year that a Rust SDK was on the way, but we're almost in April 2024 and still no signs. I want to use OpenFGA with Rust. So I have 2 questions:

  1. Is there a recommended way forward whilst there still isn't an SDK available to use OpenFGA with Rust? Can I generate a gRPC client from a protobuf or something?
  2. Is there a timeline for when the Rust SDK will be delivered? An official SDK helps sell the solution to stakeholders.

Love your work guys,

Liam

@netthier
Copy link
Author

I'm currently successfully using OpenFGA via a tonic_build-generated client.

@liamwh
Copy link

liamwh commented Apr 4, 2024

I'm currently successfully using OpenFGA via a tonic_build-generated client.

That's awesome! Do you have a repo I could reference by any chance?

Though for the maintainers, of course it would still be better to have first-party support.

@netthier
Copy link
Author

netthier commented Apr 4, 2024

I don't have it uploaded publicly, and I'm unsure how to properly package that kind of library, but it's not too difficult to set up.
I cloned https://github.com/openfga/api and ran buf export . --output=../proto to generate a directory containing the protobuf definitions of OpenFGA and its dependencies.
I then created a Rust library with the newly created proto directory next to src, with this build.rs:

use prost_wkt_build::{FileDescriptorSet, Message};
use std::{env, io::Result, path::PathBuf};

fn main() -> Result<()> {
    let out = PathBuf::from(env::var("OUT_DIR").unwrap());
    let descriptor_file = out.join("descriptors.bin");
    tonic_build::configure()
        .build_server(false)
        .build_client(true)
        .type_attribute(".", "#[derive(serde::Serialize,serde::Deserialize)]")
        .extern_path(".google.protobuf.Timestamp", "::prost_wkt_types::Timestamp")
        .extern_path(".google.protobuf.Struct", "::prost_wkt_types::Struct")
        .extern_path(".google.protobuf.Value", "::prost_wkt_types::Value")
        .file_descriptor_set_path(&descriptor_file)
        .compile(
            &[
                "proto/openfga/v1/authzmodel.proto",
                "proto/openfga/v1/errors_ignore.proto",
                "proto/openfga/v1/openapi.proto",
                "proto/openfga/v1/openfga.proto",
                "proto/openfga/v1/openfga_service.proto",
            ],
            &["proto/"],
        )
        .unwrap();

    let descriptor_bytes = std::fs::read(descriptor_file).unwrap();
    let descriptor = FileDescriptorSet::decode(&descriptor_bytes[..]).unwrap();
    prost_wkt_build::add_serde(out, descriptor);

    Ok(())
}

and this src/lib.rs:

pub use prost_types;
pub use tonic;

include!(concat!(env!("OUT_DIR"), "/openfga.v1.rs"));

@liamwh
Copy link

liamwh commented Apr 4, 2024

Thanks for this! Would you mind sending me a gist including the cargo.toml also? I believe I've repeated your instructions but get plenty the following compilation errors:

error[E0277]: the trait bound `Assertions: serde::de::Deserialize<'_>` is not satisfied
    --> /home/liam/.cargo-target/debug/build/openfga-rs-4c66487b7d4aec1f/out/openfga.v1.rs:1900:102
     |
1900 | ...ost_wkt :: typetag ; # [typetag :: serde (name = "type.googleapis.com/openfga.v1.Assertions")] impl :: prost_wkt :: MessageSe...
     |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `serde::de::Deserialize
<'_>` is not implemented for `Assertions`
     |
     = help: the following other types implement trait `serde::de::Deserialize<'de>`:
               bool
               char
               isize
               i8
               i16
               i32
               i64
               i128
             and 144 others
note: required by a bound in `erased_serde::de::deserialize`
    --> /home/liam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/erased-serde-0.4.4/src/de.rs:42:8
     |
40   | pub fn deserialize<'de, T>(deserializer: &mut dyn Deserializer<'de>) -> Result<T, Error>
     |        ----------- required by a bound in this function
41   | where
42   |     T: serde::Deserialize<'de>,
     |        ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `deserialize`
     = note: this error originates in the attribute macro `typetag::serde` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `openfga-rs` (lib) due to 152 previous errors

@rhamzeh
Copy link
Member

rhamzeh commented Apr 4, 2024

Thanks for knowledge sharing @netthier!

@liamwh for the record, we have the Rust SDK on our roadmap, but it's not anytime soon. We have some work to do to streamline the SDK Generator to bring in more consistency, and make generating and supporting newer SDKs even easier. We're making some headway there, but the bulk of the work in the generator is planned over the next 6 months, after which new SDKs will be unblocked and hopefully will be much easier to contribute and maintain.

@netthier
Copy link
Author

netthier commented Apr 4, 2024

@liamwh
Ah sorry, I dropped .type_attribute(".", "#[derive(serde::Serialize,serde::Deserialize)]") from the build configuration because I thought it was specific to my use case. Adding that should derive those traits on the OpenFGA types appropriately.
And for reference, my Cargo.toml contains the following deps (though I'm not sure if all of them are necessary for this, esp the last two non-build deps):

[dependencies]
tonic = "0.10"
prost = "0.12"
prost-types = "0.12"
prost-wkt = "0.5"
prost-wkt-types = "0.5"
serde = { version = "1", features = ["derive"] }
schemars = { version = "0.8", features = ["chrono"] }
chrono = { version = "0.4", features = ["serde"] }

[build-dependencies]
tonic-build = "0.10"
prost-wkt-build = "0.5"

EDIT: Just noticed the build.rs literally contains prost_wkt_build::add_serde at the end. This would explain the dependency on serde lol. I bet if you remove that line you can also remove the type attributes.

@liamwh
Copy link

liamwh commented Apr 8, 2024

Thanks @netthier! With this I was able to set up a public repo:

Repo: https://github.com/liamwh/openfga-rs/
Docs.rs: https://docs.rs/openfga-rs/latest/openfga_rs/

In my spare time I'll try using this and add docs to the README. Do you have any examples or pointers to help me get started? Or feel free to open a PR if you please!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rust-sdk Affects the Rust SDK sdk-request Request for a new SDK
Projects
Status: Backlog
Development

No branches or pull requests

3 participants