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

Rework remote settings server URL #6429

Merged
merged 1 commit into from
Oct 28, 2024
Merged

Conversation

bendk
Copy link
Contributor

@bendk bendk commented Oct 24, 2024

Let's update these to match the JS client:
https://github.com/mozilla-extensions/remote-settings-devtools/blob/15245fdb8e4fb5875a7866c7328ded6671ab466c/extension/experiments/remotesettings/api.js#L8-L11

This is a breaking change to the public API, but this API is not exposed via UniFFI and it's only used in 1 place:

let url = remote_settings_server.url()?;
if url.scheme() == "file" {
// Everything in `config` other than the url/path is ignored for the
// file-system - we could insist on a sub-directory, but that doesn't
// seem valuable for the use-cases we care about here.
let path = match url.to_file_path() {
Ok(path) => path,
_ => return Err(NimbusError::InvalidPath(url.into())),
};
Box::new(FileSystemClient::new(path)?)
} else {
Box::new(RemoteSettings::new(config)?)
. AFAICT, the only affect this will have is that the error message will change slightly.

Also removed the .unwrap() calls. It shouldn't matter because there's no way for .join() to fail, but it feels silly calling unwrap() from a function that returns a result.

Pull Request checklist

  • Breaking changes: This PR follows our breaking change policy
    • This PR follows the breaking change policy:
      • This PR has no breaking API changes, or
      • There are corresponding PRs for our consumer applications that resolve the breaking changes and have been approved
  • Quality: This PR builds and tests run cleanly
    • Note:
      • For changes that need extra cross-platform testing, consider adding [ci full] to the PR title.
      • If this pull request includes a breaking change, consider cutting a new release after merging.
  • Tests: This PR includes thorough tests or an explanation of why it does not
  • Changelog: This PR includes a changelog entry in CHANGELOG.md or an explanation of why it does not need one
    • Any breaking changes to Swift or Kotlin binding APIs are noted explicitly
  • Dependencies: This PR follows our dependency management guidelines
    • Any new dependencies are accompanied by a summary of the due diligence applied in selecting them.

Branch builds: add [firefox-android: branch-name] to the PR title.

@bendk bendk requested review from leplatrem and a team October 24, 2024 15:10
@codecov-commenter
Copy link

codecov-commenter commented Oct 24, 2024

Codecov Report

Attention: Patch coverage is 0% with 43 lines in your changes missing coverage. Please review.

Project coverage is 21.76%. Comparing base (8bdea9d) to head (f807f09).

Files with missing lines Patch % Lines
components/remote_settings/src/client.rs 0.00% 34 Missing ⚠️
components/remote_settings/src/config.rs 0.00% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6429      +/-   ##
==========================================
- Coverage   21.78%   21.76%   -0.02%     
==========================================
  Files         344      344              
  Lines       31028    31053      +25     
==========================================
  Hits         6759     6759              
- Misses      24269    24294      +25     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bendk bendk force-pushed the push-owyotmxrznxy branch 2 times, most recently from 4837c02 to 966b7da Compare October 24, 2024 17:27
Copy link
Contributor

@leplatrem leplatrem left a comment

Choose a reason for hiding this comment

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

I'm sorry if it wasn't ultra clear in other messages, but our convention is to not put the trailing / in the server url and build paths with {server-url}/buckets/...

(Note: I didn't put comments everywhere this has to be adjusted)

@@ -122,24 +122,29 @@ pub trait ApiClient {

/// Client for Remote settings API requests
pub struct ViaductApiClient {
/// Server base URL
///
/// This is something like `https://[domain]/v1/`. It's what's normally called the `base_url`
Copy link
Contributor

@leplatrem leplatrem Oct 25, 2024

Choose a reason for hiding this comment

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

Our convention is to not put the trailing /

/// Base URL for requests to a collections endpoint
///
/// This is something like
/// `https://[server-url]/v1/buckets/[bucket-name]/collections/[collection-name]/"
/// `https://[server-url]/buckets/[bucket-name]/collections/[collection-name]/`
Copy link
Contributor

Choose a reason for hiding this comment

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

This is correct (only if no trailing slash in server-url)

collection_url: Url,
remote_state: RemoteState,
}

impl ViaductApiClient {
fn new(server_url: Url, bucket_name: &str, collection_name: &str) -> Result<Self> {
let collection_url = server_url.join(&format!(
"v1/buckets/{bucket_name}/collections/{collection_name}/"
"buckets/{bucket_name}/collections/{collection_name}/"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"buckets/{bucket_name}/collections/{collection_name}/"
"/buckets/{bucket_name}/collections/{collection_name}/"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I avoided this because it's going to break the join. Without the trailing slash, then join treats the last component as a file rather than a directory and removes it. However, there is the path_segments_mut() method. Let me try that and see how it comes out.

@bendk bendk force-pushed the push-owyotmxrznxy branch 3 times, most recently from a181293 to 2a80bc1 Compare October 25, 2024 15:17
let mut server_url = base_url.clone();
// Push the empty string to add a trailing slash. This avoids a redirect when we hit
// the server.
Self::path_segments_mut(&mut server_url)?.push("");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using https://firefox.settings.services.mozilla.com/v1/ instead of https://firefox.settings.services.mozilla.com/v1 seems right to me. I always try to avoid hitting a redirect when I make an API call. But tell me if that's a bad idea.

Copy link
Contributor

Choose a reason for hiding this comment

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

There should not be any redirect, we don't call the server_url directly (without trailing slash)

@bendk
Copy link
Contributor Author

bendk commented Oct 25, 2024

Your v1/ vs v1 suggestion pushed me to make a bunch of changes and I'm liking the result. Encapsulating the URL creating into a single class seems like the nicest way to handle this.

@bendk bendk force-pushed the push-owyotmxrznxy branch from 2a80bc1 to 0cbe484 Compare October 25, 2024 15:24
Copy link
Contributor

@leplatrem leplatrem left a comment

Choose a reason for hiding this comment

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

This looks good, and approved to avoid blocking you longer.

Nevertheless, in order to avoid confusion between the different implementations, I would like to insist that we shouldn't put any trailing slash to the server URL.

I agree with you, it would be ugly to hit a redirect, but we don't because we consider / as the root endpoint.

So I think that with your PR, if we just add a root endpoint to your struct, we should be aligned with the other implementations 😊

Examples in kinto-http.py:

class Endpoints(object):
    endpoints = {
        "root": "{root}/",
        "batch": "{root}/batch",
        "buckets": "{root}/buckets",
        "bucket": "{root}/buckets/{bucket}",
        "history": "{root}/buckets/{bucket}/history",
        "groups": "{root}/buckets/{bucket}/groups",
        "group": "{root}/buckets/{bucket}/groups/{group}",
        "collections": "{root}/buckets/{bucket}/collections",
        "collection": "{root}/buckets/{bucket}/collections/{collection}",
        "records": "{root}/buckets/{bucket}/collections/{collection}/records",  # NOQA
        "record": "{root}/buckets/{bucket}/collections/{collection}/records/{id}",  # NOQA
    }

or kinto.js

const ENDPOINTS = {
  root: () => "/",
  bucket: (bucket?: string) => "/buckets" + (bucket ? `/${bucket}` : ""),
  collection: (bucket: string, coll?: string) =>
    `${ENDPOINTS.bucket(bucket)}/collections` + (coll ? `/${coll}` : ""),
  record: (bucket: string, coll: string, id?: string) =>
    `${ENDPOINTS.collection(bucket, coll)}/records` + (id ? `/${id}` : ""),
    // ...
    // ...
};

let collection_url = self.collection_url.clone();
let server_info = self.make_request(collection_url)?.json::<ServerInfo>()?;
let server_info = self
.make_request(self.endpoints.server_url.clone())?
Copy link
Contributor

Choose a reason for hiding this comment

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

I would call it root_url

/// Top-level URL for Remote Settings server
///
/// This has the form `https://[domain]/v1/`. It's where we get the attachment base url from.
server_url: Url,
Copy link
Contributor

Choose a reason for hiding this comment

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

In other implementations, we call this the root URL and it has the form of {server_url}/

let mut server_url = base_url.clone();
// Push the empty string to add a trailing slash. This avoids a redirect when we hit
// the server.
Self::path_segments_mut(&mut server_url)?.push("");
Copy link
Contributor

Choose a reason for hiding this comment

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

There should not be any redirect, we don't call the server_url directly (without trailing slash)

@bendk bendk force-pushed the push-owyotmxrznxy branch from 0cbe484 to 781b59c Compare October 28, 2024 21:08
Let's update these to match the JS client:
https://github.com/mozilla-extensions/remote-settings-devtools/blob/15245fdb8e4fb5875a7866c7328ded6671ab466c/extension/experiments/remotesettings/api.js#L8-L11

This is a breaking change to the public API, but this API is not exposed
via UniFFI and it's only used in 1 place:
https://github.com/mozilla/application-services/blob/50bf235b9a3a62a6b6749cd0bd7358d7b96a42e4/components/nimbus/src/stateful/client/mod.rs#L24-L35.
AFAICT, the only affect this will have is that the error message will
change slightly.

Fixed an error when downloading attachments in the new client code.  I
think I broke it with my last commit.

Also removed the `.unwrap()` calls.  It shouldn't matter because there's
no way for `.join()` to fail, but it feels silly calling `unwrap()` from
a function that returns a result.
@bendk bendk force-pushed the push-owyotmxrznxy branch from 781b59c to f807f09 Compare October 28, 2024 21:10
@bendk
Copy link
Contributor Author

bendk commented Oct 28, 2024

That makes sense. I updated the terminology to be root_url. That actually removed all references to server_url.

@bendk bendk enabled auto-merge October 28, 2024 21:17
@bendk bendk added this pull request to the merge queue Oct 28, 2024
Merged via the queue into mozilla:main with commit dbc8e8d Oct 28, 2024
16 checks passed
@bendk bendk deleted the push-owyotmxrznxy branch October 28, 2024 22:12
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.

3 participants