{"id":19705309,"url":"https://github.com/markcda/cc-server-kit","last_synced_at":"2025-02-27T13:48:16.049Z","repository":{"id":260577316,"uuid":"881724237","full_name":"markcda/cc-server-kit","owner":"markcda","description":"State-of-art simple and powerful web server based on `salvo`.","archived":false,"fork":false,"pushed_at":"2025-02-22T18:52:04.000Z","size":74,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-22T19:33:35.426Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/markcda.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-01T05:09:17.000Z","updated_at":"2025-02-22T18:51:59.000Z","dependencies_parsed_at":"2024-12-12T01:23:03.575Z","dependency_job_id":"0b8a9205-438b-43cf-96ac-0c75015cf432","html_url":"https://github.com/markcda/cc-server-kit","commit_stats":null,"previous_names":["markcda/cc-server-kit"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markcda%2Fcc-server-kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markcda%2Fcc-server-kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markcda%2Fcc-server-kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markcda%2Fcc-server-kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markcda","download_url":"https://codeload.github.com/markcda/cc-server-kit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241020436,"owners_count":19895440,"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-11T21:27:26.702Z","updated_at":"2025-02-27T13:48:16.041Z","avatar_url":"https://github.com/markcda.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CC Server Kit\n\nState-of-art simple and powerful web server based on `salvo`. Provides extended tracing, configuration-over-YAML, QUIC/HTTP3, MessagePack support, ACME, OpenAPI and OpenTelemetry features by default, with one step to CORS and WebSockets.\n\n## How's it work\n\n1. You load configuration from the file on the startup via `load_generic_config` function.\n2. You start logging, check config for misconfigurations and load the state - all just via `load_generic_state` function.\n3. You create your own `salvo::Router` and then generate server's `Future` and handle by `start` function.\n4. You manually start awaiting `server`.\n\n## 4 Quick start steps\n\n1. Create `Setup` struct.\n2. Create simple endpoints.\n3. Create `server-example.yaml` file in crate root.\n4. Just setup your application in 5 lines in `main`.\n\nYAML configuration example:\n\n```yaml\nstartup_type: http_localhost\nserver_port: 8801\nallow_oapi_access: true\noapi_frontend_type: Scalar\noapi_name: Server Test OAPI\noapi_ver: 0.0.1\noapi_api_addr: /api\nlog_level: debug\n```\n\n`Cargo.toml`:\n\n```toml\n[package]\nname = \"cc-server-example\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[dependencies]\ncc-server-kit = { git = \"https://github.com/markcda/cc-server-kit.git\", default-features = false, features = [\"oapi\", \"utils\"] }\nserde = { version = \"1\", features = [\"derive\"] }\ntokio = { version = \"1\", features = [\"macros\"] }\n```\n\nThe code itself:\n\n```rust\nuse cc_server_kit::prelude::*;\nuse serde::Deserialize;\n\n#[derive(Deserialize, Default, Clone)]\nstruct Setup {\n  #[serde(flatten)]\n  generic_values: GenericValues,\n  // this could be your global variables, such as the database URLs\n}\n\nimpl GenericSetup for Setup {\n  fn generic_values(\u0026self) -\u003e \u0026GenericValues { \u0026self.generic_values }\n  fn generic_values_mut(\u0026mut self) -\u003e \u0026mut GenericValues { \u0026mut self.generic_values; }\n}\n\n#[derive(Deserialize, Serialize, Debug, salvo::oapi::ToSchema)]\n/// Some hello\nstruct HelloData {\n  /// Hello's text\n  text: String,\n}\n\n#[endpoint(\n  tags(\"test\"),\n  request_body(content = HelloData, content_type = \"application/json\", description = \"Some JSON hello to MsgPack\"),\n  responses((status_code = 200, description = \"Some MsgPack hello\", body = HelloData, content_type = [\"application/msgpack\"]))\n)]\n#[instrument(skip_all, fields(http.uri = req.uri().path(), http.method = req.method().as_str()))]\nasync fn json_to_msgpack(req: \u0026mut Request, depot: \u0026mut Depot) -\u003e MResult\u003cMsgPack\u003cHelloData\u003e\u003e {\n  let hello = req.parse_json::\u003cHelloData\u003e().await?;\n  let app_name = depot.obtain::\u003cSetup\u003e()?.generic_values().app_name.as_str();\n  msgpack!(HelloData { text: format!(\"From `{}` application: {}\", app_name, hello.text) })\n}\n\n#[endpoint(\n  tags(\"test\"),\n  request_body(content = HelloData, content_type = \"application/msgpack\", description = \"Some MsgPack hello to JSON\"),\n  responses((status_code = 200, description = \"Some JSON hello\", body = HelloData, content_type = [\"application/json\"]))\n)]\n#[instrument(skip_all, fields(http.uri = req.uri().path(), http.method = req.method().as_str()))]\nasync fn msgpack_to_json(req: \u0026mut Request, depot: \u0026mut Depot) -\u003e MResult\u003cJson\u003cHelloData\u003e\u003e {\n  let hello = req.parse_msgpack::\u003cHelloData\u003e().await?;\n  let app_name = depot.obtain::\u003cSetup\u003e()?.generic_values().app_name.as_str();\n  json!(HelloData { text: format!(\"From `{}` application: {}\", app_name, hello.text) })\n}\n\nfn tests_router() -\u003e Router {\n  Router::new()\n    .push(Router::with_path(\"msgpack-to-json\").post(msgpack_to_json))\n    .push(Router::with_path(\"json-to-msgpack\").post(json_to_msgpack))\n}\n\n#[tokio::main]\nasync fn main() {\n  let setup = load_generic_config::\u003cSetup\u003e(\"server-example\").await.unwrap();\n  let state = load_generic_state(\u0026setup).await.unwrap();\n  let router = get_root_router_autoinject(\u0026state, setup.clone()).push(tests_router());\n  let (server, _handler) = start(state, \u0026setup, router).await.unwrap();\n  server.await\n}\n```\n\nHere we go! You can now start the server with `cargo run --release`!\n\n## Configuring your server\n\n### Startup type\n\nYou can select the startup type from this types:\n\n1. `http_localhost` - will listen `http://127.0.0.1:{port}` only\n2. `unsafe_http` - will listen `http://0.0.0.0:{port}`\n3. `https_acme` (requires `acme` feature) - will listen `https://{host}:{port}` with [ACME] support\n4. `quinn_acme` (requires both `acme` and `http3` features) - will listen `https://` and `quic://` with [ACME]\n5. `https_only` - will listen `https://{host}:{port}`\n6. `quinn` (requires `http3` feature) - will listen `https://` and `quic://`\n7. `quinn_only` (requires `http3` feature) - will listen `quic://{host}:{port}`\n\nExample:\n\n```yaml\nstartup_type: quinn\n```\n\n### Server host \u0026 server port\n\nSpecify `server_host` as IP address to listen with server (except `http_localhost` and `unsafe_http` startup types).\n\nSpecify `server_port` to listen with server. If you use your app with CC Server Kit as internal service, specify any port; if you want to expose your ports to the Internet, use `80` to HTTP and `443` for HTTPS or QUIC.\n\nAlso, if you want to specify your listening port after application start, you can use `server_port_achiever` field (see below).\n\nExample:\n\n```yaml\nstartup_type: quinn\nserver_host: 0.0.0.0\nserver_port: 443\n```\n\n### ACME domain\n\nSpecify `acme_domain` to use [ACME] (TLS ALPN-01).\n\nExample:\n\n```yaml\nstartup_type: quinn_acme\nserver_host: 0.0.0.0\nserver_port: 443\nacme_domain: tls-alpn-01.domain.com\n```\n\n### SSL key \u0026 certs\n\nExample:\n\n```yaml\nstartup_type: quinn\nserver_host: 0.0.0.0\nserver_port: 443\nssl_crt_path: certs/fullchain.pem\nssl_key_path: certs/privkey.pem\n```\n\n### Auto-migrate binary\n\nSpecify `auto_migrate_bin` field to automatically execute any binary (for example, DB migrations) before actual server start.\n\n### Allow CORS\n\nSpecify `allow_cors_domain` field to automatically manage CORS policy to given domain or domains.\n\nExample:\n\n```yaml\n# ...\nallow_cors_domain: \"https://my-domain.com\"\n```\n\n### Allow OAPI\n\nSpecify `allow_oapi_access` field to automatically generate OpenAPI specifications and provide to users.\n\nExample:\n\n```yaml\n# ...\nallow_oapi_access: true\noapi_frontend_type: Scalar # or `SwaggerUI`\noapi_name: My API\noapi_ver: 0.1.0\n```\n\n### Logging\n\nCC Server Kit uses `tracing` for logging inside routes' logic. Configuration example:\n\n```yaml\nlog_level: info       # error | warn | info | debug | trace\nlog_file_level: debug # error | warn | info | debug | trace\nlog_rolling: daily    # never | daily | hourly | minutely\nlog_rolling_max_files: 5\n```\n\nYou can also specify `open_telemetry_endpoint` to automatically send your metrics collected with `tracing` to anything like Prometheus or Jaeger.\n\n### Server port achieveing\n\nYou can specify `server_port_achiever` field to any filepath to make server wait for file creation and writing actual server port to listen to it.\n\nExample:\n\n```yaml\nstartup_type: quinn\nserver_host: 0.0.0.0\nserver_port_achiever: write/port/to/me.txt\n```\n\n### Force HTTPS\n\nTo enforce HTTPS, you should start another server via `start_force_https_redirect` function:\n\n```rust\nlet (server, handler) = start_force_https_redirect(80, 443).await.unwrap();\n```\n\n[ACME]: https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkcda%2Fcc-server-kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkcda%2Fcc-server-kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkcda%2Fcc-server-kit/lists"}