{"id":19662832,"url":"https://github.com/baskeboler/restdbxx","last_synced_at":"2025-08-07T09:14:05.542Z","repository":{"id":85110398,"uuid":"108094748","full_name":"baskeboler/restdbxx","owner":"baskeboler","description":"REST data server implemented with proxygen and rocksdb","archived":false,"fork":false,"pushed_at":"2017-12-13T01:13:24.000Z","size":128,"stargazers_count":6,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-28T21:43:35.534Z","etag":null,"topics":["asynchronous-programming","cpp11","file-server","folly","http-server","proxygen","rest-api","rocksdb"],"latest_commit_sha":null,"homepage":"http://github.yoruguan.com/restdbxx","language":"C++","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/baskeboler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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,"zenodo":null}},"created_at":"2017-10-24T07:53:11.000Z","updated_at":"2023-04-26T15:00:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"a0491ff2-b0c1-4378-aedd-a870cb36d2d6","html_url":"https://github.com/baskeboler/restdbxx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/baskeboler/restdbxx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baskeboler%2Frestdbxx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baskeboler%2Frestdbxx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baskeboler%2Frestdbxx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baskeboler%2Frestdbxx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baskeboler","download_url":"https://codeload.github.com/baskeboler/restdbxx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baskeboler%2Frestdbxx/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269230839,"owners_count":24382244,"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","status":"online","status_checked_at":"2025-08-07T02:00:09.698Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["asynchronous-programming","cpp11","file-server","folly","http-server","proxygen","rest-api","rocksdb"],"created_at":"2024-11-11T16:12:30.054Z","updated_at":"2025-08-07T09:14:05.534Z","avatar_url":"https://github.com/baskeboler.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# restdbxx\n[![Build Status](https://travis-ci.org/baskeboler/restdbxx.svg?branch=master)](https://travis-ci.org/baskeboler/restdbxx)\n\n## dependencies\n\nthe following libs should be compiled in this order:\n\n+  gflags\n+ glog\n+ boost \n+ folly\n+ rocksdb\n+ wangle\n+ proxygen\n\n## endpoints\n+ /__users\n  + post to this endpoint to create users\n  + f.e.: \n  ```json\n  {\n    \"username\": \"user\",\n    \"password\": \"pass\"\n  }\n  ```\n  + get list of users\n  + get specific user, for example /__users/username\n+ /__endpoints\n  + GET will return a list of endpoint descriptors\n  + POST will register a new endpoint, for now the following json body is valid:\n    ```json \n    {\n        \"url\": \"/new_endpoint\" \n    }\n    ```\n    + more properties in the future.\n+ /authenticate\n  + POST json like\n    ```json\n    {\n        \"username\": \"some_user\",\n        \"password\": \"somepassword\"\n    }\n    ```\n    + if successful, the service will return a json object with an access token.\n    + for protected requests, include the following headers\n      + RESTDBXX_AUTH_TOKEN with provided access token string\n      + RESTDBXX_AUTH_USERNAME with username\n      + if valid, request will proceed, otherwise it will be rejected.\n+ /test_endpoint\n\n## implementation notes\nThis is an example of implementing proxygen request handlers asynchronously.\n\n```c++\nfolly::Promise\u003cSomeResult\u003e promise;\nauto f = promise.getFuture();\nfolly:EventBaseManager::get()-\u003egetEventBase()-\u003erunInLoop(\n    [p = std::move(promise), this]() mutable {\n        // this is run in a different thread\n        SomeResult result = doSomeWork();\n        p.setValue(result);\n    }\n);\nf.then([this](SomeResult\u0026 res) {\n    // we send the response from the original thread\n    proxygen::ResponseBuilder(downstream_)\n        .status(200, \"OK\")\n        .body(res.getBuffer())\n        .sendWithEOM()\n});\n\n```\n\n## JsonClient\n\nUtility class created with the purpose of making GET requests to remote servers less painful.\n\n### usage\n\nYou initialize the class with the requests details and then you invoke the following\nmethod:\n\n\u003e `void JsonClient::fetch(proxygen::HTTPMessage *req, folly::Promise\u003cfolly::dynamic\u003e \u0026promise)`\n\nPay attention to the promise that the function receives, you should get a future from that \npromise before calling `fetch()`.\n\nHere is an example:\n\n```cpp\nfolly::Promise\u003cfolly::dynamic\u003e promise;\n  auto f = promise.getFuture();\n  folly::EventBaseManager::get()-\u003egetEventBase()\n      -\u003erunInLoop([comic, p = std::move(promise), this]() mutable {\n        auto req = new HTTPMessage();\n        std::stringstream ss;\n        ss \u003c\u003c \"https://xkcd.com/\";\n        if (comic) {\n          ss \u003c\u003c comic.value() \u003c\u003c \"/\";\n        }\n        ss \u003c\u003c \"info.0.json\";\n        req-\u003esetURL(ss.str());\n        req-\u003esetMethod(HTTPMethod::GET);\n        client-\u003efetch(req, p);\n      });\n  f.then([this](folly::dynamic \u0026comic) mutable {\n    ResponseBuilder(downstream_)\n        .status(200, \"OK\")\n        .header(\"RESTDBXX_QUERY_TIME\", std::to_string(client-\u003eget_elapsed()))\n        .header(proxygen::HTTPHeaderCode::HTTP_HEADER_CONTENT_TYPE, \"application/json\")\n        .body(folly::toPrettyJson(comic))\n        .sendWithEOM();\n    return;\n  }).onError([this](const std::runtime_error \u0026e) {\n    ResponseBuilder(downstream_)\n        .status(500, \"unexpected error\")\n        .body(e.what())\n        .sendWithEOM();\n\n  });\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaskeboler%2Frestdbxx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaskeboler%2Frestdbxx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaskeboler%2Frestdbxx/lists"}