{"id":18278112,"url":"https://github.com/angular-rust/ux-webmachine","last_synced_at":"2025-04-09T04:38:27.697Z","repository":{"id":62444566,"uuid":"498082434","full_name":"angular-rust/ux-webmachine","owner":"angular-rust","description":null,"archived":false,"fork":false,"pushed_at":"2022-05-31T19:10:54.000Z","size":36,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T02:03:37.420Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/angular-rust.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-30T20:06:19.000Z","updated_at":"2022-06-03T02:36:54.000Z","dependencies_parsed_at":"2022-11-01T22:30:50.490Z","dependency_job_id":null,"html_url":"https://github.com/angular-rust/ux-webmachine","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angular-rust%2Fux-webmachine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angular-rust%2Fux-webmachine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angular-rust%2Fux-webmachine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/angular-rust%2Fux-webmachine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/angular-rust","download_url":"https://codeload.github.com/angular-rust/ux-webmachine/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980830,"owners_count":21027803,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-05T12:23:02.128Z","updated_at":"2025-04-09T04:38:27.032Z","avatar_url":"https://github.com/angular-rust.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ux-webmachine\n\nAsyncronous webmachines in Rust\n\n\u003eFork of https://github.com/uglyog/webmachine-rust.git\n\nPort of Webmachine-Ruby (https://github.com/webmachine/webmachine-ruby) to Rust.\n\nux-webmachine is a port of the Ruby version of webmachine. It implements a finite state machine for the HTTP protocol\nthat provides semantic HTTP handling (based on the [diagram from the webmachine project](https://webmachine.github.io/images/http-headers-status-v3.png)).\nIt is basically a HTTP toolkit for building HTTP-friendly applications using the [Hyper](https://crates.io/crates/hyper) rust crate.\n\nWebmachine-rust works with Hyper and sits between the Hyper Handler and your application code. It provides a resource struct\nwith callbacks to handle the decisions required as the state machine is executed against the request with the following sequence.\n\nREQUEST -\u003e Hyper Handler -\u003e WebmachineDispatcher -\u003e WebmachineResource -\u003e Your application code -\u003e WebmachineResponse -\u003e Hyper -\u003e RESPONSE\n\n## Features\n\n- Handles the hard parts of content negotiation, conditional requests, and response codes for you.\n- Provides a resource struct with points of extension to let you describe what is relevant about your particular resource.\n\n## Missing Features\n\nCurrently, the following features from webmachine-ruby have not been implemented:\n\n- Visual debugger\n- Streaming response bodies\n\n## Implementation Deficiencies:\n\nThis implementation has the following deficiencies:\n\n- Automatically decoding request bodies and encoding response bodies.\n- No easy mechanism to generate bodies with different content types (e.g. JSON vs. XML).\n- No easy mechanism for handling sub-paths in a resource.\n- Dynamically determining the methods allowed on the resource.\n\n## Getting started with Hyper\n\nFollow the getting started documentation from the Hyper crate to setup a Hyper service for your server.\nYou need to define a WebmachineDispatcher that maps resource paths to your webmachine resources (WebmachineResource).\nEach WebmachineResource defines all the callbacks (via Closures) and values required to implement a resource.\nThe WebmachineDispatcher implementes the Hyper Service trait, so you can pass it to the `make_service_fn`.\n\nNote: This example uses the maplit crate to provide the `btreemap` macro and the log crate for the logging macros.\n\n ```rust\n use hyper::server::Server;\n use webmachine_rust::*;\n use webmachine_rust::context::*;\n use webmachine_rust::headers::*;\n use serde_json::{Value, json};\n use std::io::Read;\n use std::net::SocketAddr;\n use hyper::service::make_service_fn;\n use std::convert::Infallible;\n\n // setup the dispatcher, which maps paths to resources. The requirement of make_service_fn is\n // that it has a static lifetime\n fn dispatcher() -\u003e WebmachineDispatcher\u003c'static\u003e {\n   WebmachineDispatcher {\n       routes: btreemap!{\n          \"/myresource\" =\u003e WebmachineResource {\n            // Methods allowed on this resource\n            allowed_methods: vec![\"OPTIONS\", \"GET\", \"HEAD\", \"POST\"],\n            // if the resource exists callback\n            resource_exists: callback(\u0026|_, _| true),\n            // callback to render the response for the resource\n            render_response: callback(\u0026|_, _| {\n                let json_response = json!({\n                   \"data\": [1, 2, 3, 4]\n                });\n                Some(json_response.to_string())\n            }),\n            // callback to process the post for the resource\n            process_post: callback(\u0026|_, _|  /* Handle the post here */ Ok(true) ),\n            // default everything else\n            .. WebmachineResource::default()\n          }\n      }\n   }\n }\n\n async fn start_server() -\u003e Result\u003c(), String\u003e {\n   // Create a Hyper server that delegates to the dispatcher\n   let addr = \"0.0.0.0:8080\".parse().unwrap();\n   let make_svc = make_service_fn(|_| async { Ok::\u003c_, Infallible\u003e(dispatcher()) });\n   match Server::try_bind(\u0026addr) {\n     Ok(server) =\u003e {\n       // start the actual server\n       server.serve(make_svc).await;\n       Ok(())\n     },\n     Err(err) =\u003e {\n       error!(\"could not start server: {}\", err);\n       Err(format!(\"could not start server: {}\", err))\n     }\n   }\n }\n ```\n\n## Example implementations\n\nFor an example of a project using this crate, have a look at the [Pact Mock Server](https://github.com/pact-foundation/pact-reference/tree/master/rust/v1/pact_mock_server_cli) from the Pact reference implementation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangular-rust%2Fux-webmachine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangular-rust%2Fux-webmachine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangular-rust%2Fux-webmachine/lists"}