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

Make page tokens shorter #923

Open
david-crespo opened this issue Feb 29, 2024 · 1 comment
Open

Make page tokens shorter #923

david-crespo opened this issue Feb 29, 2024 · 1 comment

Comments

@david-crespo
Copy link
Contributor

david-crespo commented Feb 29, 2024

This is helpful but not essential for oxidecomputer/console#1102, putting page tokens in console URLs. The real blocker is #436.


Page tokens are base64ed JSON and they come out pretty long. Here's an example:

> atob('eyJ2IjoidjEiLCJwYWdlX3N0YXJ0Ijp7InNvcnRfYnkiOiJuYW1lX2FzY2VuZGluZyIsInByb2plY3QiOiJhbGFuIiwibGFzdF9zZWVuIjoienp6LWluc3QtMTE0In19')
'{"v":"v1","page_start":{"sort_by":"name_ascending","project":"alan","last_seen":"zzz-inst-114"}}' 

oxiderack.com/projects/mock-project/instances?page=eyJ2IjoidjEiLCJwYWdlX3N0YXJ0Ijp7InNvcnRfYnkiOiJuYW1lX2FzY2VuZGluZyIsInByb2plY3QiOiJhbGFuIiwibGFzdF9zZWVuIjoienp6LWluc3QtMTE0In19 would work fine I guess, but to me it looks a bit silly. Here's where we do the serialization:

let token_bytes = {
let serialized_token =
SerializedToken { v: PaginationVersion::V1, page_start };
let json_bytes =
serde_json::to_vec(&serialized_token).map_err(|e| {
HttpError::for_internal_error(format!(
"failed to serialize token: {}",
e
))
})?;
URL_SAFE.encode(json_bytes)
};

It should be pretty easy to encode the token in a more efficient format like MessagePack and maybe reduce the size of the data itself by, e.g., making some keys shorter.

Method Length of token
Current: base64 JSON string 128
MessagePack JSON as-is 104
MessagePack JSON with page_start -> p 92
MessagePack struct directly with serde_rmp (code below) 52
Rust program to compare base64 JSON and MessagePack
# Cargo.toml
[package]
name = "serialization-test"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rmp-serde = "0.15.4"
base64 = "0.13.0"
// src/main.rs

extern crate base64;
extern crate rmp_serde as rmps;
extern crate serde;
extern crate serde_json;

use serde::{Deserialize, Serialize};
use std::error::Error;

#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct MyStruct {
    v: String,
    page_start: PageStart,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct PageStart {
    sort_by: String,
    project: String,
    last_seen: String,
}

fn main() -> Result<(), Box<dyn Error>> {
    let data = MyStruct {
        v: "v1".to_owned(),
        page_start: PageStart {
            sort_by: "name_ascending".to_owned(),
            project: "alan".to_owned(),
            last_seen: "zzz-inst-114".to_owned(),
        },
    };

    // Serialize with JSON
    let json_data = serde_json::to_vec(&data)?;
    let encoded_json = base64::encode(&json_data);

    // Serialize with MessagePack
    let msgpack_data = rmps::to_vec(&data)?;
    let encoded_msgpack = base64::encode(&msgpack_data);

    // Compare the lengths of the encoded strings
    println!("Base64 JSON Length: {}", encoded_json.len());
    println!("Base64 MessagePack Length: {}", encoded_msgpack.len());

    Ok(())
}
@david-crespo david-crespo changed the title It would be nice if page tokens were shorter Make page tokens shorter Feb 29, 2024
@ahl
Copy link
Collaborator

ahl commented Feb 29, 2024

What about compressing the text first?

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 a pull request may close this issue.

2 participants