mirror of
https://github.com/fluencelabs/fluid
synced 2025-06-17 15:21:20 +00:00
rust-workshop => backend-rust
This commit is contained in:
24
backend-rust/step1-json-api/Cargo.toml
Normal file
24
backend-rust/step1-json-api/Cargo.toml
Normal file
@ -0,0 +1,24 @@
|
||||
[package]
|
||||
name = "fluid"
|
||||
version = "0.1.0"
|
||||
authors = ["Fluence Labs"]
|
||||
publish = false
|
||||
description = "Decentralized feed built on Fluence"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "fluid"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[profile.release]
|
||||
debug = false
|
||||
lto = true
|
||||
opt-level = "z"
|
||||
panic = "abort"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "=1.0.88", features = ["derive"] }
|
||||
serde_json = { version = "=1.0.38", features = ["raw_value"] }
|
||||
log = "0.4"
|
||||
fluence = { version = "0.1.6", features = ["wasm_logger"] }
|
40
backend-rust/step1-json-api/run.sh
Executable file
40
backend-rust/step1-json-api/run.sh
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p wasm
|
||||
|
||||
# Build fluid WASM module
|
||||
echo "Building..."
|
||||
cargo +nightly build --target wasm32-unknown-unknown --release >/dev/null
|
||||
cp target/wasm32-unknown-unknown/release/*.wasm ./wasm/
|
||||
echo
|
||||
|
||||
# Run it all on 30000 port with default Fluence API
|
||||
echo "Running..."
|
||||
docker rm -f frun &>/dev/null || true
|
||||
echo 'docker run -d --name frun --rm -v "$(pwd)/wasm:/code" -p 30000:30000 fluencelabs/frun:latest'
|
||||
docker run -d --name frun --rm -v "$(pwd)/wasm:/code" -p 30000:30000 fluencelabs/frun:latest >/dev/null
|
||||
echo
|
||||
|
||||
# Wait for app to be initialized
|
||||
sleep 1 && (docker logs -f frun 2>&1 &) | grep -q initialized && sleep 1
|
||||
|
||||
# Send our username to the application
|
||||
echo -e "Sending request..."
|
||||
|
||||
# Assign json to a variable using heredoc technique
|
||||
JSON=$(cat <<JSON
|
||||
{"action":"Post","message":"I'm nice, you're nice, it's nice!","username":"random_joe"}
|
||||
JSON
|
||||
)
|
||||
|
||||
# Send json as a request, and receive result
|
||||
RESPONSE=$(curl -s 'http://localhost:30000/apps/1/tx' --data $'sessionId/0\n'"$JSON" --compressed | jq -r .result.data | base64 -D)
|
||||
|
||||
# Parse result as JSON and print to console
|
||||
echo -e "$RESPONSE" | jq .
|
||||
|
||||
# Remove frun container
|
||||
echo -e "Stopping..."
|
||||
docker rm -f frun >/dev/null
|
30
backend-rust/step1-json-api/src/api.rs
Normal file
30
backend-rust/step1-json-api/src/api.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use crate::errors::{err_msg, Error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::value::RawValue;
|
||||
|
||||
pub type AppResult<T> = ::std::result::Result<T, Box<Error>>;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "action")]
|
||||
pub enum Request {
|
||||
Post { message: String, username: String },
|
||||
Fetch { username: Option<String> },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum Response {
|
||||
Post { count: i32 },
|
||||
Fetch { posts: Box<RawValue> },
|
||||
Error { error: String },
|
||||
}
|
||||
|
||||
pub fn parse(s: String) -> AppResult<Request> {
|
||||
serde_json::from_str(s.as_str())
|
||||
.map_err(|e| err_msg(&format!("unable to parse json request from {}: {}", s, e)))
|
||||
}
|
||||
|
||||
pub fn serialize(response: &Response) -> String {
|
||||
serde_json::to_string(response)
|
||||
.unwrap_or(format!("Unable to serialize response {:?}", response))
|
||||
}
|
16
backend-rust/step1-json-api/src/errors.rs
Normal file
16
backend-rust/step1-json-api/src/errors.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Error(String);
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn err_msg(s: &str) -> Box<Error> {
|
||||
Error(s.to_string()).into()
|
||||
}
|
60
backend-rust/step1-json-api/src/lib.rs
Normal file
60
backend-rust/step1-json-api/src/lib.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use fluence::sdk::*;
|
||||
use serde_json::value::RawValue;
|
||||
|
||||
use api::Request;
|
||||
use api::Response;
|
||||
|
||||
use crate::api::AppResult;
|
||||
use crate::errors::err_msg;
|
||||
|
||||
pub mod api;
|
||||
pub mod errors;
|
||||
pub mod model;
|
||||
|
||||
fn init() {
|
||||
logger::WasmLogger::init_with_level(log::Level::Info).unwrap();
|
||||
model::create_scheme().unwrap();
|
||||
}
|
||||
|
||||
#[invocation_handler(init_fn = init)]
|
||||
fn run(arg: String) -> String {
|
||||
// Parse and username JSON request
|
||||
let result = api::parse(arg).and_then(|request| match request {
|
||||
Request::Post { message, username } => add_post(message, username),
|
||||
Request::Fetch { username } => fetch_posts(username),
|
||||
});
|
||||
|
||||
let result = match result {
|
||||
Ok(good) => good,
|
||||
Err(error) => Response::Error {
|
||||
error: error.to_string(),
|
||||
},
|
||||
};
|
||||
|
||||
// Serialize response to JSON
|
||||
api::serialize(&result)
|
||||
}
|
||||
|
||||
fn add_post(msg: String, username: String) -> AppResult<Response> {
|
||||
// Store post
|
||||
model::add_post(msg, username)?;
|
||||
// Get total number of posts
|
||||
let count = model::get_posts_count()?;
|
||||
|
||||
Ok(Response::Post { count })
|
||||
}
|
||||
|
||||
fn fetch_posts(username: Option<String>) -> AppResult<Response> {
|
||||
let posts_str = match username {
|
||||
// Get all posts if no filter username was passed
|
||||
None => model::get_all_posts()?,
|
||||
// Or get only posts from specified author
|
||||
Some(h) => model::get_posts_by_username(h)?,
|
||||
};
|
||||
|
||||
// Some Rust-specific detail to play nice with serialization, doesn't matter
|
||||
let raw = RawValue::from_string(posts_str)
|
||||
.map_err(|e| err_msg(&format!("Can't create RawValue: {}", e)))?;
|
||||
|
||||
Ok(Response::Fetch { posts: raw })
|
||||
}
|
25
backend-rust/step1-json-api/src/model.rs
Normal file
25
backend-rust/step1-json-api/src/model.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use crate::api::AppResult;
|
||||
use log;
|
||||
|
||||
pub fn create_scheme() -> AppResult<()> {
|
||||
Ok(log::info!("creating scheme"))
|
||||
}
|
||||
|
||||
pub fn add_post(msg: String, username: String) -> AppResult<()> {
|
||||
Ok(log::info!("add post {} {}", msg, username))
|
||||
}
|
||||
|
||||
pub fn get_all_posts() -> AppResult<String> {
|
||||
log::info!("get all posts");
|
||||
Ok("[]".to_string())
|
||||
}
|
||||
|
||||
pub fn get_posts_by_username(username: String) -> AppResult<String> {
|
||||
log::info!("get all posts by username {}", username);
|
||||
Ok("[]".to_string())
|
||||
}
|
||||
|
||||
pub fn get_posts_count() -> AppResult<i32> {
|
||||
log::info!("get posts count");
|
||||
Ok(0)
|
||||
}
|
Reference in New Issue
Block a user