Firestore: Invalid request routing header
Thanks for the amazing library.
Environment details
- Programming language: Rust
- OS: MacOS 15.7.2
- Language runtime version: v1.93.0-nightly
- Package version:
firestore: 0.0.0
Issue
I am using the experimental firestore library at the moment.
google-cloud-firestore = { git = "https://github.com/googleapis/google-cloud-rust", rev = "50f65b0c024f080888c62ca33fe19af35dc607e6" }
There is an issue with the generated code.
I received this error below:
Error: Firestore("Batch write failed: the service reports an error with code INVALID_ARGUMENT described as: Invalid request routing header &database
=projects/{project-name}/databases/{database-name}. Please fill in the request header with format x-goog-request-params:project_id={project-name}&database_id={database-name}. Please refer to https://firebase.google.com/docs/firestore/manage-databases#access_a_named_database_with_a_client_library for more details.")
After I noticed the issue, I forked the library, google-cloud-rust, and tried to see whether the generated code was wrong.
I made some changes to src/firestore/src/generated/gapic/transport.rs
# Before
let x_goog_request_params = [Some(&req)
.map(|m| &m.database)
.map(|s| s.as_str())
.map(|v| format!("database={v}"))]
.into_iter()
.flatten()
.fold(String::new(), |b, p| b + "&" + &p);
# After
let x_goog_request_params = gaxi::routing_parameter::format(&[
// Extract project_id from "projects/{project_id}/databases/{database_id}"
gaxi::routing_parameter::value(
Some(req.database.as_str()),
&[gaxi::routing_parameter::Segment::Literal("projects/")],
&[gaxi::routing_parameter::Segment::SingleWildcard],
&[gaxi::routing_parameter::Segment::Literal("/databases/"), gaxi::routing_parameter::Segment::SingleWildcard],
)
.map(|v| ("project_id", v)),
// Extract database_id from "projects/{project_id}/databases/{database_id}"
gaxi::routing_parameter::value(
Some(req.database.as_str()),
&[gaxi::routing_parameter::Segment::Literal("projects/"), gaxi::routing_parameter::Segment::SingleWildcard, gaxi::routing_parameter::Segment::Literal("/databases/")],
&[gaxi::routing_parameter::Segment::SingleWildcard],
&[],
)
.map(|v| ("database_id", v)),
]);
After the manual changes, everything started to work.
After a further investigation of the generated code.
on googleapis, the proto definitions need this block
option (google.api.routing) = {
routing_parameters {
field: "database"
path_template: "projects/{project_id=*}/**"
}
routing_parameters {
field: "database"
path_template: "projects/*/databases/{database_id=*}/**"
}
};
Edit: I opened a PR
Thanks for the detailed bug report and the investigation. I think in most other languages a hand-written layer adds these routing headers. Your patch sounds like a better solution to me, but there may be good reasons to prefer a hand-written layer that I may be missing.
Oh, and I should say that writing this layer is in our roadmap, but we have prioritized other services ahead of Firestore.
For other Googlers: b/275088289 may be of interest.
Hi @coryan,
Thank you for getting back to me. Is there a way I could contribute to this project, especially to firestore?
Many thanks.