From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: Proxmox Backup Server development discussion
<pbs-devel@lists.proxmox.com>,
Dominik Csapak <d.csapak@proxmox.com>
Subject: Re: [pbs-devel] [PATCH proxmox-backup v2 3/3] examples: add example for a simple rest server with a small api
Date: Wed, 29 Sep 2021 08:41:26 +0200 [thread overview]
Message-ID: <03f68008-c297-51f8-10f0-87d9edfc1da7@proxmox.com> (raw)
In-Reply-To: <20210928091152.2151682-4-d.csapak@proxmox.com>
On 28.09.21 11:11, Dominik Csapak wrote:
> show how to generally start a daemon that serves a rest api + index page
>
> api calls are:
well they are prefixed with `/api2` that's really something that we need to
make configurable, for any future project I definitively do not want to use
the rather confusing /api2 from the start, that can be rather easily adapted
in the client's central HTTP request handling code.
> / GET listing
> /ping GET returns "pong"
> /items GET lists existing items
> POST lets user create new items
> /items/{id} GET returns the content of a single item
> PUT updates an item
> DELETE deletes an item
>
> Contains a small dummy user/authinfo
>
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> changes from v1:
> * use hyper::server::conn::AddrIncoming::from_listener
>
> proxmox-rest-server/Cargo.toml | 5 +
> proxmox-rest-server/examples/rest_server.rs | 219 ++++++++++++++++++++
> 2 files changed, 224 insertions(+)
> create mode 100644 proxmox-rest-server/examples/rest_server.rs
>
> diff --git a/proxmox-rest-server/Cargo.toml b/proxmox-rest-server/Cargo.toml
> index b0e53d19..a6d25b8b 100644
> --- a/proxmox-rest-server/Cargo.toml
> +++ b/proxmox-rest-server/Cargo.toml
> @@ -5,6 +5,11 @@ authors = ["Proxmox Support Team <support@proxmox.com>"]
> edition = "2018"
> description = "REST server implementation"
>
> +# for example
> +[dev-dependencies]
> +proxmox = { version = "0.13.4", features = ["router","api-macro"] }
0.13.4 is already outdated, do we even need tho have that version target so strict as
else I'd go with "0.13" for now..
> +pbs-runtime = { path = "../pbs-runtime" }
> +
> [dependencies]
> anyhow = "1.0"
> futures = "0.3"
> diff --git a/proxmox-rest-server/examples/rest_server.rs b/proxmox-rest-server/examples/rest_server.rs
> new file mode 100644
> index 00000000..89efbcb2
> --- /dev/null
> +++ b/proxmox-rest-server/examples/rest_server.rs
> @@ -0,0 +1,219 @@
> +use std::sync::{Arc, Mutex};
> +use std::collections::HashMap;
> +
> +use anyhow::{bail, format_err, Error};
> +use futures::{FutureExt, TryFutureExt};
> +use lazy_static::lazy_static;
> +
> +use proxmox::api::{api, router::SubdirMap, Router, RpcEnvironmentType, UserInformation};
> +use proxmox::list_subdirs_api_method;
> +use proxmox_rest_server::{ApiAuth, ApiConfig, AuthError, RestServer};
> +
> +// Create a Dummy User info and auth system
> +// Normally this would check and authenticate the user
> +struct DummyUserInfo;
> +
> +impl UserInformation for DummyUserInfo {
> + fn is_superuser(&self, _userid: &str) -> bool {
> + true
> + }
> + fn is_group_member(&self, _userid: &str, group: &str) -> bool {
> + group == "Group"
> + }
> + fn lookup_privs(&self, _userid: &str, _path: &[&str]) -> u64 {
> + u64::MAX
> + }
> +}
> +
> +struct DummyAuth;
> +
> +impl ApiAuth for DummyAuth {
> + fn check_auth(
> + &self,
> + _headers: &http::HeaderMap,
> + _method: &hyper::Method,
> + ) -> Result<(String, Box<dyn UserInformation + Sync + Send>), AuthError> {
> + // get some global/cached userinfo
> + let userinfo = DummyUserInfo;
> + // Do some user checks, e.g. cookie/csrf
> + Ok(("User".to_string(), Box::new(userinfo)))
> + }
> +}
> +
> +// this should return the index page of the webserver
> +// iow. what the user browses to
above fits in one line even with 80 cc, and in rust we normally go always for 100cc.
> +fn get_index(
> + _auth_id: Option<String>,
> + _language: Option<String>,
> + _api: &ApiConfig,
> + _parts: http::request::Parts,
> +) -> http::Response<hyper::Body> {
> + // build an index page
> + http::Response::builder()
> + .body("hello world".into())
maybe a mini html thingy with the API description from above + links to the GET calls would
be nice to have?
> +async fn run() -> Result<(), Error> {
> +
> + // we first have to configure the api environment (basedir etc.)
> +
> + let config = ApiConfig::new(
> + "/var/tmp/",
> + &ROUTER,
> + RpcEnvironmentType::PUBLIC,
> + Arc::new(DummyAuth {}),
> + get_index,
> + )?;
> + let rest_server = RestServer::new(config);
> +
> + // then we have to create a daemon that listens, accepts and serves
> + // the api to clients
> + proxmox_rest_server::daemon::create_daemon(
> + ([127, 0, 0, 1], 65000).into(),
> + move |listener, ready| {
> + let incoming = hyper::server::conn::AddrIncoming::from_listener(listener)?;
> +
> + Ok(ready
> + .and_then(|_| hyper::Server::builder(incoming)
> + .serve(rest_server)
> + .map_err(Error::from)
> + )
> + .map_err(|err| eprintln!("ERR: {}", err))
> + .map(|test| println!("OK: {}", test.is_ok())))
closing parenthesis jungle ^^
Can you at least place the closing one from Ok() one a new line or does rustfmt does not like that?
> + },
> + "example_server",
> + ).await?;
> +
> + Ok(())
> +}
> +
> +fn main() -> Result<(), Error> {
> + pbs_runtime::main(run())
here I agree with Dietmar, avoiding that dependency would be nice for the example.
> +}
>
next prev parent reply other threads:[~2021-09-29 6:42 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-28 9:11 [pbs-devel] [PATCH proxmox-backup v2 0/3] add rest_server example Dominik Csapak
2021-09-28 9:11 ` [pbs-devel] [PATCH proxmox-backup v2 1/3] rest-server: use hypers AddrStream for proxmox-backup-api Dominik Csapak
2021-09-29 6:27 ` Thomas Lamprecht
2021-09-28 9:11 ` [pbs-devel] [PATCH proxmox-backup v2 2/3] remove tools/async_io.rs Dominik Csapak
2021-09-28 9:11 ` [pbs-devel] [PATCH proxmox-backup v2 3/3] examples: add example for a simple rest server with a small api Dominik Csapak
2021-09-29 6:41 ` Thomas Lamprecht [this message]
2021-09-29 5:19 Dietmar Maurer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=03f68008-c297-51f8-10f0-87d9edfc1da7@proxmox.com \
--to=t.lamprecht@proxmox.com \
--cc=d.csapak@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.