{"id":46744,"date":"2023-01-20T00:00:00","date_gmt":"2023-01-20T08:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/introducing-the-rust-client-for-griddb\/"},"modified":"2026-03-30T13:43:21","modified_gmt":"2026-03-30T20:43:21","slug":"introducing-the-rust-client-for-griddb","status":"publish","type":"post","link":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/introducing-the-rust-client-for-griddb\/","title":{"rendered":"Introducing the Rust Client for GridDB"},"content":{"rendered":"<p>The Rust programming language is a static, compiled language which &#8220;emphasizes performance, type safety, and concurrency.&#8221; It has grown very quickly in the limited time it has been available and consistently ranks as the most loved language in the <a href=\"https:\/\/insights.stackoverflow.com\/survey\/2021#section-most-loved-dreaded-and-wanted-programming-scripting-and-markup-languages\">annual stackoverflow developer survey<\/a>.<\/p>\n<p>Rust&#8217;s growing popularity is exactly why the GridDB development team has written the <a href=\"https:\/\/github.com\/griddb\/rust_client\">GridDB rust client<\/a> for interfacing with the database. As with the other <a href=\"https:\/\/github.com\/griddb\">GridDB connectors<\/a>, this will allow you to write programs which can directly read and write to your running GridDB server.<\/p>\n<p>For this article, we will discuss installing Rust, the Rust client, and then go over some simple CRUD commands to showcase the basic functionality of this client; this includes actions such as querying your <a href=\"https:\/\/docs.griddb.net\/architecture\/data-model.html\">containers<\/a>.<\/p>\n<p>Before we dive into the article, you can follow along with the full source code here:<\/p>\n<div class=\"clipboard\">\n<pre><code>$ git clone --branch blog_1_rust https:\/\/github.com\/griddbnet\/Blogs.git<\/code><\/pre>\n<\/div>\n<p>Also a quick note: we are using a dataset of which we have been using in the most recent blogs that was taken from Kaggle. You can read more about it in our <a href=\"https:\/\/griddb.net\/en\/blog\/using-the-griddb-import-export-tools-to-migrate-from-postgresql-to-griddb\/\">PostgreSQL to GridDB Migration blog<\/a><\/p>\n<h2>Getting Started<\/h2>\n<p>To get started, you will need to have GridDB up and running either via <a href=\"https:\/\/docs.griddb.net\/latest\/gettingstarted\/using-apt\/#install-with-deb\">direct installation<\/a>, or through <a href=\"https:\/\/griddb.net\/en\/blog\/improve-your-devops-with-griddb-server-and-client-docker-containers\/\">Docker<\/a>.<\/p>\n<p>You will also need the <a href=\"https:\/\/github.com\/griddb\/c_client\">GridDB c_client<\/a> (NOTE: if you installed GridDB via apt or yum, the c_client is already included in your installation). And lastly you will need to install the Rust programming language as well:<\/p>\n<div class=\"clipboard\">\n<pre><code>$ curl https:\/\/sh.rustup.rs -sSf | sh<\/code><\/pre>\n<\/div>\n<p>Another thing you will need is to install the compiler clang.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\"> # Ubuntu\n$ sudo apt-get install clang-10 libclang-10-dev <\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\"> # CentOS\n$ sudo yum install llvm-toolset-7.0\n$ scl enable llvm-toolset-7.0 bash<\/code><\/pre>\n<\/div>\n<p>Once you have these prereqs ready on your machine, you can navigate into the <code>rust_client<\/code> directory and run the Rust build command:<\/p>\n<div class=\"clipboard\">\n<pre><code>$ cargo build<\/code><\/pre>\n<\/div>\n<p>This command is a part of the Rust toolchain which will read the <code>Cargo.toml<\/code> file and build out the project for you. From here you can run the sample code included in the official client&#8217;s repo to see if everything is working as intended. If instead you have cloned the repo for this project, please hang on and we will discuss a bit further before we include how to run the included code.<\/p>\n<h2>Writing Rust Source Code<\/h2>\n<p>To begin writing Rust source code to interface with your GridDB server, we will begin with importing the proper GridDB crate and then connecting to our server.<\/p>\n<p>So, to start, let&#8217;s import the library and then import the functions we aim to use in our code.<\/p>\n<p>And note: we are now working out of the source code included at the top and bottom of this article.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">use std::time::Duration;\nuse griddb::get_value;\nuse griddb::griddb::ContainerInfo::*;\nuse griddb::griddb::StoreFactory::*;\nuse griddb::griddb::Type::*;\nuse griddb::griddb::Value::*;\nuse griddb::gsvec;\nuse chrono:: Utc;<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">[package]\nname = \"griddb_rust_client_blog\"\nversion = \"0.1.0\"\nedition = \"2021\"<\/code><\/pre>\n<\/div>\n<p>The imports at the top of each file work similarly to other languages (such as Python). Here, we are calling the <a href=\"https:\/\/lib.rs\/crates\/griddb\">konector_db<\/a> library which is where the GridDB Rust client exists.<\/p>\n<p>As for the package name, you can name it however you like; here we are naming it something generic for this blog.<\/p>\n<h3>Using the GridDB Rust Client<\/h3>\n<p>To add the GridDB Rust client into your own repo\/project, you will need to add the following to your <code>Cargo.toml<\/code> file.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">[dependencies]\ngriddb = \"0.5.0\"\nchrono = \"0.4\"\nconvert_case = \"^0.3.0\"<\/code><\/pre>\n<\/div>\n<p>This simply means that the Rust toolchain will make sure the GridDB rust connector source code gets built and included with our project during compile time when we run <code>cargo build<\/code> or <code>cargo run<\/code>.<\/p>\n<p>To run this project, you can clone the repository and then run each of the examples similar to the sample code from the official repo<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ cargo run --example connect\n\nSuccessfully Connected to GridDB<\/code><\/pre>\n<\/div>\n<p>Our server values are hardcoded into the example files in the <code>examples<\/code> directory, so if the command fails, please make sure you have GridDB up and running and change the DB connection details if needed.<\/p>\n<h3>Connecting to GridDB<\/h3>\n<p>For the source code in this article we will place ALL code inside our <code>main<\/code> function for ease of use.<\/p>\n<p>Similar to the other GridDB connectors, we will connect to our database using the factory store and by inputting our connection details:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">        \/\/ get default factory\n        let factory = StoreFactory::get_instance();\n        let properties = vec![\n            (\"notification_member\", \"127.0.0.1:10001\"),\n            (\"cluster_name\", \"myCluster\"),\n            (\"user\", \"admin\"),\n            (\"password\", \"admin\"),\n        ];<\/code><\/pre>\n<\/div>\n<p>Differing slightly from the GridDB source code examples, we have hardcoded in our GridDB connection details right inside our code to make running and debugging a smoother experience.<\/p>\n<p>Once we have the proper connection details, we can establish our connection and get our <code>gridstore<\/code> function<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">        \/\/ get gridstore function\n        let store = match factory.get_store(properties) {\n            Ok(result) => result,\n            Err(error) => panic!(\"Error factory get_store() with error code: {:?}\", error),\n        };<\/code><\/pre>\n<\/div>\n<p>Here we are using Rust&#8217;s <code>match statement<\/code>, which works a bit like the classic <code>switch<\/code> statement found in <code>C<\/code> and <code>JavaScript<\/code>. The first arm of the match is evaluated, <code>get_store<\/code> in this case, if all goes well, it returns <code>Ok<\/code> and we return the <code>result<\/code> into <code>store<\/code>; if it fails, the program will throw an error, panic, and then print out the error.<\/p>\n<p>Once that store variable is populated, we are connected to our database and we can start creating containers.<\/p>\n<h2>Create, Read, Update, Delete &#8211; CRUD with GridDB<\/h2>\n<p>To showcase the Rust Client, we wanted to show the basic functionality of interfacing with a database, SQL or otherwise, through the typical CRUD commands. We will have one big function which will run through and create some containers, drop containers, add rows, delete rows, query via TQL and via the API, and then finally running through a simple aggregation function through TQL.<\/p>\n<p>Before I get into the full source code, let&#8217;s again take a look at our <code>Cargo.toml<\/code> file. This time I will show the whole file which will showcase all of the dependencies we are using:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">[package]\nname = \"griddb_rust_client_blog\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[dependencies]\ngriddb = \"0.5.0\"\nchrono = \"0.4\"\nconvert_case = \"^0.3.0\"<\/code><\/pre>\n<\/div>\n<h3>Create (&amp; Delete)<\/h3>\n<p>When you are making your <code>colinfo<\/code> variable which will house your GridDB container schema, please be mindful that the data types match up with the Rust ones. For example, a GridDB DOUBLE datatype must be <code>f64<\/code> and so forth.<\/p>\n<p>To get an idea of what translates into what, you can look at the API documentation: <a href=\"https:\/\/griddb.org\/rust_client\/RustAPIReference.htm\">here<\/a>, namely the Data-Type Mapping section.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">    \/\/ Creating Time Series Container\n    let tsinfo = ContainerInfo::ContainerInfo(\n        \"device13\",\n        vec![\n            (\"ts\", Type::Timestamp),\n            (\"co\", Type::Double),\n            (\"humidity\", Type::Double),\n            (\"light\", Type::Bool),\n            (\"lpg\", Type::Double),\n            (\"motion\", Type::Bool),\n            (\"smoke\", Type::Double),\n            (\"temp\", Type::Double),\n        ],\n        ContainerType::TimeSeries,\n        true,\n    );<\/code><\/pre>\n<\/div>\n<p>And once the schema and all information is set, we do more of the usual GridDB stuff: <code>put_container<\/code>.<\/p>\n<p>But before we run through actually creating our container (and its schema) inside of our database, we will call <code>drop_container<\/code> on our container first. This ensures that everytime our example source code is run, it is starting from fresh. You will notice that no error is thrown deleting a container that does not exist, so it&#8217;s similar to the SQL command <code>DROP TABLE IF EXISTS<\/code>.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">\n    store.drop_container(\"device13\");\n\n    match store.put_container(&tsinfo, false) {\n        Ok(result) => result,\n        Err(error) => panic!(\"Error store put_container() with error code: {:?}\", error),\n    };<\/code><\/pre>\n<\/div>\n<p>We can also create a <code>Collection<\/code> container with a similar set up. In the following snippet, we will create a small &#8220;device master&#8221; type collection container which will sort of mimic a real-world type schema in which you have a sensor container and a sort-of record-keeping container.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">    \/\/ Creating Collection Container\n    let colinfo  = ContainerInfo::ContainerInfo(\n        \"deviceMaster2\",\n        vec![\n            (\"sensorID\", Type::String),\n            (\"location\", Type::String),\n        ],\n        ContainerType::Collection,\n        true,\n    );\n\n    store.drop_container(\"deviceMaster2\");\n\n    let con = match store.put_container(&colinfo, false) {\n        Ok(result) => result,\n        Err(error) => panic!(\"Error store put_container() with error code: {:?}\", error),\n    };\n    con.set_auto_commit(false);\n    con.create_index(\"sensorID\", IndexType::Default);\n    con.commit();\n    println!(\"Successfully created Collection container: deviceMaster2\");<\/code><\/pre>\n<\/div>\n<p>The only difference between the time series container and the collection is that we manually created the index for our rowkey here, but in the time series containers, it is auto-made by definition of the container type.<\/p>\n<p>And again, to run this example code:<\/p>\n<div class=\"clipboard\">\n<pre><code>$ cargo run --example create_containers<\/code><\/pre>\n<\/div>\n<p>Once you run this, you will now have these two containers created in your running GridDB server. You can verify with the <a href=\"https:\/\/github.com\/griddb\/cli\">GridDB CLI<\/a> tool. You can use it like so:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ sudo su gsadm\n$ gs_sh\ngs> showcontainer device13<\/code><\/pre>\n<\/div>\n<pre><code>Database    : public\nName        : device13\nType        : TIME_SERIES\nPartition ID: 8\nDataAffinity: -\n\nCompression Method : NO\nCompression Window : -\nRow Expiration Time: -\nRow Expiration Division Count: -\n\nColumns:\nNo  Name                  Type            CSTR  RowKey   Compression   \n------------------------------------------------------------------------------\n0  ts                    TIMESTAMP       NN    [RowKey]  \n1  co                    DOUBLE                          \n2  humidity              DOUBLE                          \n3  light                 BOOL                            \n4  lpg                   DOUBLE                          \n5  motion                BOOL                            \n6  smoke                 DOUBLE                          \n7  temp                  DOUBLE \n<\/code><\/pre>\n<h3>Insert Data (Create)<\/h3>\n<p>Next, let&#8217;s try pushing some data into our container. We can accomplish this with a rather simple API call of <code>.put<\/code> like so:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">        \/\/ Grab current time to use as time value for container\n        let timestamp: Timestamp = Timestamp {\n            value: Utc::now().timestamp_millis(),\n        };\n\n        \/\/ following the schema laid out in the create_container.rs file\n        ts.put(gsvec![timestamp, 0.004342, 49.0, false, 0.00753242, false, 0.0212323, 23.2]);\n\n        let timestamp_second: Timestamp = Timestamp {\n            value: Utc::now().timestamp_millis() + 1000,\n        };\n        ts.put(gsvec![timestamp_second, 0.0065342, 31.0, false, 0.753242, false, 0.02653323, 27.2]);\n        \/\/ rows aren't pushed until the commit is called\n        ts.commit();<\/code><\/pre>\n<\/div>\n<p>Here we are using the variable of <code>ts<\/code>, which now represents our device container, to put data directly into there, we use the <code>gsvec<\/code> from the GridDB client and create a vector with all of the proper data types that our schema expects. We simply enter in all proper data directly into the container. Here we are placing two separate rows into our container, each with different times as the row key (for the 2nd rowkey, we simply add 1000ms to the original timestamp to guarantee a new row is made).<\/p>\n<div class=\"clipboard\">\n<pre><code>$ cargo run --example insert_data<\/code><\/pre>\n<\/div>\n<p>Again, you can verify that the data was actually inserted:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ sudo su gsadm\n$ gs_sh\ngs[public]> select * from device13;\n2 results. (5 ms)\ngs[public]> get<\/code><\/pre>\n<\/div>\n<pre><code>ts,co,humidity,light,lpg,motion,smoke,temp\n2022-11-28T21:40:12.250Z,0.004342,49.0,false,0.00753242,false,0.0212323,23.2\n2022-11-28T21:40:13.251Z,0.0065342,31.0,false,0.753242,false,0.02653323,27.2\nThe 2 results had been acquired.\n<\/code><\/pre>\n<h3>Read (via TQL)<\/h3>\n<p>Next, let&#8217;s try a more complex reading of our data; instead of calling a row directly via rowkey and api, let&#8217;s instead use the <code>.query<\/code> api call to run a real <a href=\"https:\/\/docs.griddb.net\/tqlreference\/\">TQL<\/a> query.<\/p>\n<p>First the source code:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">    let query = match ts.query(\"select *\") {\n        Ok(result) => result,\n        Err(error) => panic!(\"Error container query data with error code: {:?}\", error),\n    };\n    let row_set = match query.fetch() {\n        Ok(result) => result,\n        Err(error) => panic!(\"Error query fetch() data with error code: {:?}\", error),\n    };\n\n    while row_set.has_next() {\n        let row_data = match row_set.next() {\n            Ok(result) => result,\n            Err(error) => panic!(\"Error row set next() row with error code: {:?}\", error),\n        };\n        let ts: Timestamp = get_value![row_data[0]];\n        let timestamp_number: i64 = ts.value;\n        let co: f64 = get_value![row_data[1]];\n        let humidity: f64 = get_value![row_data[2]];\n        let light: bool = get_value![row_data[3]];\n        let lpg: f64 = get_value![row_data[4]];\n        let motion: bool = get_value![row_data[5]];\n        let smoke: f64 = get_value![row_data[6]];\n        let temp: f64 = get_value![row_data[7]];\n        let tup_query = (timestamp_number, co, humidity, light, lpg, motion, smoke, temp);\n        println!(\n            \"Device13: \n            ts={0} co={1} humidity={2} light={3} lpg={4} motion={5} smoke={6} temp={7}\",\n            tup_query.0,\n            tup_query.1,\n            tup_query.2,\n            tup_query.3,\n            tup_query.4,\n            tup_query.5,\n            tup_query.6,\n            tup_query.7\n        );\n    }<\/code><\/pre>\n<\/div>\n<p>Again here we are using the con variable to make our API calls. Because we already know which container is being targeted, there is no need to indicate which container in our query; we simply select which columns we want with no qualifiers. From there, we take the query variable and run fetch against it to perform our search. Our results are saved inside a row_set.<\/p>\n<p>Once that row_set is populated, we can loop through each row returned and simply get the value for each column in the row and print out the results. This process is similar to the programming connectors available for GridDB.<\/p>\n<p>Up to this point, you can run this and you&#8217;ll end up with two rows in your device container. You can query using this program and you can also view the results using the <a href=\"https:\/\/github.com\/griddb\/cli\">GridDB CLI<\/a>.<\/p>\n<div class=\"clipboard\">\n<pre><code>$ cargo run --example read_data<\/code><\/pre>\n<\/div>\n<h3>Update<\/h3>\n<p>Next, let&#8217;s read from our database. Despite only having two rows inside of our container at this point, I want to do a quick lookup for a specific row of data, grab the timestamp (rowkey) and then follow it up with a row update.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">\n        let query = match ts.query(\"select * where temp = 23.2\") {\n            Ok(result) => result,\n            Err(error) => panic!(\"Error container query data with error code: {:?}\", error),\n        };\n        let row_set = match query.fetch() {\n            Ok(result) => result,\n            Err(error) => panic!(\"Error query fetch() data with error code: {:?}\", error),\n        };\n\n        \/\/ Init timestamp to current time\n        let mut timestamp: Timestamp = Timestamp {\n            value: Utc::now().timestamp_millis(),\n        };\n\n        while row_set.has_next() {\n            let row_data = match row_set.next() {\n                Ok(result) => result,\n                Err(error) => panic!(\"Error row set next() row with error code: {:?}\", error),\n            };\n            timestamp = get_value![row_data[0]];\n        }\n\n        ts.put(gsvec![timestamp, 0.214342, 43.32, true, 0.00753242, true, 0.0212323, 23.2]);\n\n        ts.commit();<\/code><\/pre>\n<\/div>\n<p>There is quite a lot going on here, so let&#8217;s walk through it. First, we are using <code>query<\/code> again to do a TQL search to look up some data point. We are doing this because we need to grab the rowkey of our row we intend to update.<\/p>\n<p>So in this case, we do a row lookup, if our query is successful, we will iterate through all of the rows that match our lookup query. We will then save the timestamp returned to us by our query into our <code>timestamp<\/code> variable and then use that information to update a row.<\/p>\n<p>So once we have our rowkey, if we use <code>.put<\/code> on a row that already exists, instead of producing an error, it will simply update that row with the new values that we push onto it.<\/p>\n<div class=\"clipboard\">\n<pre><code>$ cargo run --example update_data<\/code><\/pre>\n<\/div>\n<p>Once this runs, we will update the humidity from our first row which matched our query of finding a row with a temperature of exactly 23.2. So the update will change humidity from 49 to 43.32. We can verify this with our CLI tool or with our <code>read_data<\/code> rust example:<\/p>\n<div class=\"clipboard\">\n<pre><code>$ cargo run --example read_data<\/code><\/pre>\n<\/div>\n<pre><code>Finished dev [unoptimized + debuginfo] target(s) in 0.08s\nRunning `target\/debug\/examples\/read_data`\nDevice13:\n            ts=1669671612250 co=0.214342 *humidity=43.32* light=true lpg=0.00753242 motion=true smoke=0.0212323 temp=23.2\nDevice13:\n            ts=1669671613251 co=0.0065342 humidity=31 light=false lpg=0.753242 motion=false smoke=0.02653323 temp=27.2\n<\/code><\/pre>\n<h3>Delete<\/h3>\n<p>To delete a row, you can easily use the <code>.remove<\/code> API call. Similar to the update call, you will need the rowkey of the row you are targeting. In our case, we will need the precise timestamp of the row we intend to delete. Once we have that information (likely through a query lookup), you can easily delete the row:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">        while row_set.has_next() {\n            let row_data = match row_set.next() {\n                Ok(result) => result,\n                Err(error) => panic!(\"Error row set next() row with error code: {:?}\", error),\n            };\n            timestamp = get_value![row_data[0]];\n        }\n\n        ts.remove(timestamp);\n        ts.commit();<\/code><\/pre>\n<\/div>\n<div class=\"clipboard\">\n<pre><code>$ cargo run --example delete_data<\/code><\/pre>\n<\/div>\n<p>To check we can use CLI or <code>read_data<\/code>. This time, let&#8217;s use the CLI:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ sudo su gsadm\n$ gs_sh\ngs[public]> select * from device13;\n1 results. (2 ms)\ngs[public]> get<\/code><\/pre>\n<\/div>\n<pre><code>ts,co,humidity,light,lpg,motion,smoke,temp\n2022-11-28T21:40:13.251Z,0.0065342,31.0,false,0.753242,false,0.02653323,27.2\nThe 1 results had been acquired.\n<\/code><\/pre>\n<p>We now only have one row of data inserted inside of our <code>device13<\/code> container.<\/p>\n<h2>Aggregation Queries<\/h2>\n<p>Lastly, we&#8217;d like to go over a simple aggregation query through the use of TQL. You can find about them here: <a href=\"https:\/\/docs.griddb.net\/tqlreference\/tql-syntax-and-calculation-functions\/#aggregation-operations-general\">TQL documentation<\/a><\/p>\n<p>For this example, we will simply perform a search for temps over a certain threshold, and then find the average temp in that time span. Because we only have two rows of data in this example, it won&#8217;t exactly be useful data, but it will illuminate possibilities and how this function works.<\/p>\n<p>For this example, we will go over both <code>TIME_AVG<\/code> and <code>TIME_SAMPLING<\/code>. Both of which are explained in more detail in the link above.<\/p>\n<p>First we will go over the <code>TIME_AVG<\/code>. The way to do it is simply to enter in the column you&#8217;d like to get the weight time average for. It will then do the math for every single relevant row in your whole container and spit out a singular value.<\/p>\n<p>And because our previous working examples of data were very small (~2 rows of data does not make for interesting analysis), we will use one of the containers from this <a href=\"https:\/\/www.kaggle.com\/datasets\/garystafford\/environmental-sensor-data-132k\">Kaggle dataset<\/a>. You can read about ingesting this dataset from our previous <a href=\"\">blog<\/a>.<\/p>\n<p>In this case, we will simply use <code>device1<\/code>.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">    let ts = match store.get_container(\"device1\") {\n        Ok(result) => result,\n        Err(error) => panic!(\"Error store put_container() with error code: {:?}\", error),\n    };\n\n \/\/ Aggregation Time Series Time Avg: https:\/\/www.toshiba-sol.co.jp\/en\/pro\/griddb\/docs-en\/v4_0_3\/GridDB_API_Reference.html#sec-3-3-3\n    let average_query = format!(\"select TIME_AVG(humidity)\");\n\n    let agg_query = match ts.query(&average_query) {\n        Ok(result) => result,\n        Err(error) => panic!(\n            \"Error container query aggregation data with error code: {}\",\n            error\n        ),\n    };\n    let agg_result = match agg_query.fetch() {\n        Ok(result) => result,\n        Err(error) => panic!(\n            \"Error query fetch() aggregation data with error code: {}\",\n            error\n        ),\n    };\n    let agg_data = match agg_result.next_aggregation() {\n        Ok(result) => result,\n        Err(error) => panic!(\n            \"Error row set next() aggregation row with error code: {}\",\n            error\n        ),\n    };\n    println!(\" humidity time avg = {:}\",agg_data.get_as_f64().1);<\/code><\/pre>\n<\/div>\n<p>The above source code looks long but it&#8217;s no different than what we&#8217;ve already been doing. It simply takes in our TQL query and then prints out the result. First we fetch the results, and then use the <code>next_aggregation<\/code> API call to get our value and print it out into the console.<\/p>\n<p>Next we will try to use the <code>TIME_SAMPLE<\/code> function.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-rust\">    \/\/ TIME SAMPLE from Time Series Aggregation functionality using TQL\n    let time_sample = format!(\"select TIME_SAMPLING(humidity, TIMESTAMP('2020-07-18T11:22:33.444Z'), TIMESTAMP('2020-07-22T11:22:33.444Z'), 1, HOUR)\");\n    println!(\"Running Query: {}\",  time_sample);\n    let agg_query_two = match ts.query(&time_sample) {\n        Ok(result) => result,\n        Err(error) => panic!(\n            \"Error container query aggregation data with error code: {}\",\n            error\n        ),\n    };\n    let agg_result_two = match agg_query_two.fetch() {\n        Ok(result) => result,\n        Err(error) => panic!(\n            \"Error query fetch() aggregation data with error code: {}\",\n            error\n        ),\n    };\n\n    while agg_result_two.has_next() {\n        let row_data = match agg_result_two.next() {\n            Ok(result) => result,\n            Err(error) => panic!(\"Error row set next() row with error code: {:?}\", error),\n        };\n        let ts: Timestamp = get_value![row_data[0]];\n        let timestamp_number: i64 = ts.value;\n        let co: f64 = get_value![row_data[1]];\n        let humidity: f64 = get_value![row_data[2]];\n        let light: bool = get_value![row_data[3]];\n        let lpg: f64 = get_value![row_data[4]];\n        let motion: bool = get_value![row_data[5]];\n        let smoke: f64 = get_value![row_data[6]];\n        let temp: f64 = get_value![row_data[7]];\n        let tup_query = (timestamp_number, co, humidity, light, lpg, motion, smoke, temp);\n        println!(\n            \"Device13: \n            ts={0} co={1} humidity={2} light={3} lpg={4} motion={5} smoke={6} temp={7}\",\n            tup_query.0,\n            tup_query.1,\n            tup_query.2,\n            tup_query.3,\n            tup_query.4,\n            tup_query.5,\n            tup_query.6,\n            tup_query.7\n        );\n    }<\/code><\/pre>\n<\/div>\n<p>Here we are essentially running the same code as our <code>read_data<\/code> function, just with a more interesting and complex query. We are looking up the <code>TIME_SAMPLING<\/code> in our <code>device1<\/code> dataset. This actual query string looks like this: <code>let time_sample = format!(\"select TIME_SAMPLING(humidity, TIMESTAMP('2020-07-18T11:22:33.444Z'), TIMESTAMP('2020-07-22T11:22:33.444Z'), 1, HOUR)\");<\/code>. We are telling our program to give us a sampling of the dataset between the explicit values we are giving in the query, in this case four days of data, in intervals of one hour.<\/p>\n<p>And then we are iterating through the returned results and printing out the results to the console.<\/p>\n<div class=\"clipboard\">\n<pre><code>$ cargo run --example timeseries_aggregation<\/code><\/pre>\n<\/div>\n<p>Here is what the result looks like (though this is not the entirety of the rows):<\/p>\n<pre><code>humidity time avg = 50.81422729710963\nRunning Query: select TIME_SAMPLING(humidity, TIMESTAMP('2020-07-18T11:22:33.444Z'), TIMESTAMP('2020-07-22T11:22:33.444Z'), 1, HOUR)\nDevice13:\n            ts=1595071353444 co=0.0057382469167573434 humidity=52.29999923706055 light=false lpg=0.008506583886712459 motion=false smoke=0.022858971137213444 temp=22\nDevice13:\n            ts=1595074953444 co=0.0056719601223669276 humidity=52.70000076293945 light=false lpg=0.008435383766205812 motion=false smoke=0.022654654779928257 temp=22\nDevice13:\n            ts=1595078553444 co=0.0056825985719608325 humidity=53.5235710144043 light=false lpg=0.008446826202354823 motion=false smoke=0.022687482170072902 temp=22.3\nDevice13:\n            ts=1595082153444 co=0.005747325011217979 humidity=51.92147445678711 light=false lpg=0.008516317111357271 motion=false smoke=0.022886910748059562 temp=21.7\nDevice13:\n            ts=1595085753444 co=0.0062171975352361755 humidity=54.908409118652344 light=false lpg=0.009014482964305905 motion=false smoke=0.024319772878645333 temp=21.8\nDevice13:\n            ts=1595089353444 co=0.006172104950567534 humidity=51.70000076293945 light=false lpg=0.008967138511929578 motion=false smoke=0.02418336009283044 temp=21.3\n<\/code><\/pre>\n<p>And just for fun, let&#8217;s take a look at these queries inside of our GridDB CLI:<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ sudo su gsadm\n$ gs_sh\ngs[public]> tql device1 select TIME_AVG(humidity);\n1 results. (2 ms)\ngs[public]> get<\/code><\/pre>\n<\/div>\n<pre><code>Result\n50.81422729710963\nThe 1 results had been acquired.\n<\/code><\/pre>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">gs[public]> tql device1 select TIME_SAMPLING(humidity, TIMESTAMP('2020-07-18T11:22:33.444Z'), TIMESTAMP('2020-07-22T11:22:33.444Z'), 1, HOUR);\n37 results. (0 ms)\ngs[public]> get<\/code><\/pre>\n<\/div>\n<pre><code>ts,co,humidity,light,lpg,motion,smoke,temp\n2020-07-18T11:22:33.444Z,0.0030488793379940217,77.0,false,0.005383691572564569,false,0.014022828989540865,19.799999237060547\n2020-07-18T12:22:33.444Z,0.0029050147565559603,76.65528106689453,false,0.005198697479294309,false,0.013508733329556249,19.799999237060547\n2020-07-18T13:22:33.444Z,0.002872341154862943,76.61731719970703,false,0.005156332935627952,false,0.013391176782176004,19.799999237060547\n2020-07-18T14:22:33.444Z,0.002612589347788125,75.37261199951172,false,0.004814621044662395,false,0.012445419108693902,19.5\n2020-07-18T15:22:33.444Z,0.003655886924967606,75.85926818847656,false,0.006139350359130843,false,0.016134931599636852,19.299999237060547\n2020-07-18T16:22:33.444Z,0.003655886924967606,74.72727966308594,false,0.006139350359130843,false,0.016134931599636852,19.0\n<\/code><\/pre>\n<h2>Conclusion<\/h2>\n<p>And with that, we have installed and explored using the brand new GridDB rust client. If you are interested in learning more, I recommend looking at the other example code in the official repository and creating your own applications.<\/p>\n<p>Full source can be found here: <a href=\"https:\/\/github.com\/griddbnet\/Blogs\/tree\/blog_1_rust\">GitHub<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Rust programming language is a static, compiled language which &#8220;emphasizes performance, type safety, and concurrency.&#8221; It has grown very quickly in the limited time it has been available and consistently ranks as the most loved language in the annual stackoverflow developer survey. Rust&#8217;s growing popularity is exactly why the GridDB development team has written [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":29256,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46744","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Introducing the Rust Client for GridDB | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"The Rust programming language is a static, compiled language which &quot;emphasizes performance, type safety, and concurrency.&quot; It has grown very quickly in\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introducing the Rust Client for GridDB | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"The Rust programming language is a static, compiled language which &quot;emphasizes performance, type safety, and concurrency.&quot; It has grown very quickly in\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-01-20T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-30T20:43:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2023\/01\/rust.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1160\" \/>\n\t<meta property=\"og:image:height\" content=\"653\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Israel\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Israel\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/\"},\"author\":{\"name\":\"Israel\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/c8a430e7156a9e10af73b1fbb46c2740\"},\"headline\":\"Introducing the Rust Client for GridDB\",\"datePublished\":\"2023-01-20T08:00:00+00:00\",\"dateModified\":\"2026-03-30T20:43:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/\"},\"wordCount\":2165,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2023\/01\/rust.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/\",\"name\":\"Introducing the Rust Client for GridDB | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2023\/01\/rust.png\",\"datePublished\":\"2023-01-20T08:00:00+00:00\",\"dateModified\":\"2026-03-30T20:43:21+00:00\",\"description\":\"The Rust programming language is a static, compiled language which \\\"emphasizes performance, type safety, and concurrency.\\\" It has grown very quickly in\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2023\/01\/rust.png\",\"contentUrl\":\"\/wp-content\/uploads\/2023\/01\/rust.png\",\"width\":1160,\"height\":653},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb.net\/en\/#website\",\"url\":\"https:\/\/griddb.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/c8a430e7156a9e10af73b1fbb46c2740\",\"name\":\"Israel\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4df8cfc155402a2928d11f80b0220037b8bd26c4f1b19c4598d826e0306e6307?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4df8cfc155402a2928d11f80b0220037b8bd26c4f1b19c4598d826e0306e6307?s=96&d=mm&r=g\",\"caption\":\"Israel\"},\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/israel\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Introducing the Rust Client for GridDB | GridDB: Open Source Time Series Database for IoT","description":"The Rust programming language is a static, compiled language which \"emphasizes performance, type safety, and concurrency.\" It has grown very quickly in","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/","og_locale":"en_US","og_type":"article","og_title":"Introducing the Rust Client for GridDB | GridDB: Open Source Time Series Database for IoT","og_description":"The Rust programming language is a static, compiled language which \"emphasizes performance, type safety, and concurrency.\" It has grown very quickly in","og_url":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2023-01-20T08:00:00+00:00","article_modified_time":"2026-03-30T20:43:21+00:00","og_image":[{"width":1160,"height":653,"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2023\/01\/rust.png","type":"image\/png"}],"author":"Israel","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"Israel","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/"},"author":{"name":"Israel","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/c8a430e7156a9e10af73b1fbb46c2740"},"headline":"Introducing the Rust Client for GridDB","datePublished":"2023-01-20T08:00:00+00:00","dateModified":"2026-03-30T20:43:21+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/"},"wordCount":2165,"commentCount":0,"publisher":{"@id":"https:\/\/griddb.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2023\/01\/rust.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/","url":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/","name":"Introducing the Rust Client for GridDB | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2023\/01\/rust.png","datePublished":"2023-01-20T08:00:00+00:00","dateModified":"2026-03-30T20:43:21+00:00","description":"The Rust programming language is a static, compiled language which \"emphasizes performance, type safety, and concurrency.\" It has grown very quickly in","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/introducing-the-rust-client-for-griddb\/#primaryimage","url":"\/wp-content\/uploads\/2023\/01\/rust.png","contentUrl":"\/wp-content\/uploads\/2023\/01\/rust.png","width":1160,"height":653},{"@type":"WebSite","@id":"https:\/\/griddb.net\/en\/#website","url":"https:\/\/griddb.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/c8a430e7156a9e10af73b1fbb46c2740","name":"Israel","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4df8cfc155402a2928d11f80b0220037b8bd26c4f1b19c4598d826e0306e6307?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4df8cfc155402a2928d11f80b0220037b8bd26c4f1b19c4598d826e0306e6307?s=96&d=mm&r=g","caption":"Israel"},"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/israel\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46744","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/comments?post=46744"}],"version-history":[{"count":3,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46744\/revisions"}],"predecessor-version":[{"id":55144,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46744\/revisions\/55144"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media\/29256"}],"wp:attachment":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media?parent=46744"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/categories?post=46744"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/tags?post=46744"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}