Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split state into a separate parameter #715

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,3 @@ contributors the benefit of the doubt and having a sincere willingness to admit
that you *might* be wrong is critical for any successful open collaboration.

Don't be a bad actor.

## Developer Certificate of Origin
All contributors must read and agree to the [Developer Certificate of
Origin (DCO)](../CERTIFICATE).

The DCO allows us to accept contributions from people to the project, similarly
to how a license allows us to distribute our code.
32 changes: 0 additions & 32 deletions .github/ISSUE_TEMPLATE/bug_report.md

This file was deleted.

16 changes: 0 additions & 16 deletions .github/ISSUE_TEMPLATE/feature_request.md

This file was deleted.

13 changes: 0 additions & 13 deletions .github/ISSUE_TEMPLATE/question.md

This file was deleted.

28 changes: 0 additions & 28 deletions .github/PULL_REQUEST_TEMPLATE.md

This file was deleted.

17 changes: 0 additions & 17 deletions .github/stale.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:

- uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: nightly
override: true

- name: setup
Expand Down
12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "tide"
version = "0.13.0"
description = "Serve the web – HTTP server framework"
description = "A minimal and pragmatic Rust web application framework built for rapid development"
authors = [
"Aaron Turon <[email protected]>",
"Yoshua Wuyts <[email protected]>",
Expand All @@ -26,7 +26,7 @@ rustdoc-args = ["--cfg", "feature=\"docs\""]
[features]
default = ["h1-server", "logger", "sessions"]
h1-server = ["async-h1"]
logger = []
logger = ["femme"]
docs = ["unstable"]
sessions = ["async-session"]
unstable = []
Expand All @@ -39,10 +39,12 @@ async-session = { version = "2.0.0", optional = true }
async-sse = "4.0.0"
async-std = { version = "1.6.0", features = ["unstable"] }
async-trait = "0.1.36"
femme = "2.0.1"
femme = { version = "2.0.1", optional = true }
futures-util = "0.3.5"
http-types = "2.2.1"
http-types = "2.4.0"
http-client = { version = "6.0.0", default-features = false }
kv-log-macro = "1.0.4"
log = { version = "0.4.13", features = ["kv_unstable_std"] }
pin-project-lite = "0.1.7"
route-recognizer = "0.2.0"
serde = "1.0.102"
Expand All @@ -56,7 +58,7 @@ lazy_static = "1.4.0"
logtest = "2.0.0"
portpicker = "0.1.0"
serde = { version = "1.0.102", features = ["derive"] }
surf = { version = "2.0.0-alpha.3", default-features = false, features = ["h1-client"] }
surf = { version = "2.0.0-alpha.7", default-features = false, features = ["h1-client"] }
tempfile = "3.1.0"

[[test]]
Expand Down
42 changes: 33 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,16 @@
</h3>
</div>

A modular web framework built around async/await
Tide is a minimal and pragmatic Rust web application framework built for
rapid development. It comes with a robust set of features that make building
async web applications and APIs easier and more fun.

## Getting started

Add two dependencies to your project's `Cargo.toml` file: `tide` itself, and `async-std` with the feature `attributes` enabled:
In order to build a web app in Rust you need an HTTP server, and an async
runtime. After running `cargo init` add the following lines to your
`Cargo.toml` file:

```toml
# Example, use the version numbers you need
tide = "0.13.0"
Expand All @@ -54,25 +59,43 @@ async-std = { version = "1.6.0", features = ["attributes"] }

## Examples

**Hello World**
Create an HTTP server that receives a JSON body, validates it, and responds
with a confirmation message.

```rust
use tide::Request;
use tide::prelude::*;

#[derive(Debug, Deserialize)]
struct Animal {
name: String,
legs: u8,
}

#[async_std::main]
async fn main() -> Result<(), std::io::Error> {
tide::log::start();
async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.at("/").get(|_| async { Ok("Hello, world!") });
app.at("/orders/shoes").post(order_shoes);
app.listen("127.0.0.1:8080").await?;
Ok(())
}

async fn order_shoes(mut req: Request, _state: tide::State<()>) -> tide::Result {
let Animal { name, legs } = req.body_json().await?;
Ok(format!("Hello, {}! I've put in an order for {} shoes", name, legs).into())
}
```

To try [the included examples](https://github.com/http-rs/tide/tree/main/examples), check out this repository and run
```sh
$ cargo run --example # shows a list of available examples
$ cargo run --example hello
$ curl localhost:8000/orders/shoes -d '{ "name": "Chashu", "legs": 4 }'
Hello, Chashu! I've put in an order for 4 shoes

$ curl localhost:8000/orders/shoes -d '{ "name": "Mary Millipede", "legs": 750 }'
number too large to fit in target type
```

See more examples in the [examples](https://github.com/http-rs/tide/tree/main/examples) directory.

## Tide's design:
- [Rising Tide: building a modular web framework in the open](https://rustasync.github.io/team/2018/09/11/tide.html)
- [Routing and extraction in Tide: a first sketch](https://rustasync.github.io/team/2018/10/16/tide-routing.html)
Expand Down Expand Up @@ -104,6 +127,7 @@ team. Use at your own risk.</sup>
* [tide-trace](https://github.com/no9/tide-trace)
* [tide-tracing](https://github.com/ethanboxx/tide-tracing)
* [opentelemetry-tide](https://github.com/asaaki/opentelemetry-tide)
* [driftwood](https://github.com/jbr/driftwood) http logging middleware

### Session Stores
* [async-redis-session](https://github.com/jbr/async-redis-session)
Expand Down
2 changes: 1 addition & 1 deletion examples/catflap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ async fn main() -> Result<(), std::io::Error> {
use std::{env, net::TcpListener, os::unix::io::FromRawFd};
tide::log::start();
let mut app = tide::new();
app.at("/").get(|_| async { Ok(CHANGE_THIS_TEXT) });
app.at("/").get(|_, _| async { Ok(CHANGE_THIS_TEXT) });

const CHANGE_THIS_TEXT: &str = "hello world!";

Expand Down
2 changes: 1 addition & 1 deletion examples/chunked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use tide::Body;
async fn main() -> Result<(), std::io::Error> {
tide::log::start();
let mut app = tide::new();
app.at("/").get(|_| async {
app.at("/").get(|_, _| async {
// File sends are chunked by default.
Ok(Body::from_file(file!()).await?)
});
Expand Down
4 changes: 2 additions & 2 deletions examples/concurrent_listeners.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ async fn main() -> Result<(), std::io::Error> {
tide::log::start();
let mut app = tide::new();

app.at("/").get(|request: Request<_>| async move {
app.at("/").get(|req: Request, _| async move {
Ok(format!(
"Hi! You reached this app through: {}",
request.local_addr().unwrap_or("an unknown port")
req.local_addr().unwrap_or("an unknown port")
))
});

Expand Down
8 changes: 4 additions & 4 deletions examples/cookies.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use tide::http::Cookie;
use tide::{Request, Response, StatusCode};
use tide::{Request, Response, State, StatusCode};

/// Tide will use the the `Cookies`'s `Extract` implementation to build this parameter.
///
async fn retrieve_cookie(req: Request<()>) -> tide::Result<String> {
async fn retrieve_cookie(req: Request, _: State<()>) -> tide::Result<String> {
Ok(format!("hello cookies: {:?}", req.cookie("hello").unwrap()))
}

async fn insert_cookie(_req: Request<()>) -> tide::Result {
async fn insert_cookie(_req: Request, _: State<()>) -> tide::Result {
let mut res = Response::new(StatusCode::Ok);
res.insert_cookie(Cookie::new("hello", "world"));
Ok(res)
}

async fn remove_cookie(_req: Request<()>) -> tide::Result {
async fn remove_cookie(_req: Request, _: State<()>) -> tide::Result {
let mut res = Response::new(StatusCode::Ok);
res.remove_cookie(Cookie::named("hello"));
Ok(res)
Expand Down
4 changes: 2 additions & 2 deletions examples/error_handling.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::io::ErrorKind;

use tide::utils::After;
use tide::{Body, Request, Response, Result, StatusCode};
use tide::{Body, Response, Result, StatusCode};

#[async_std::main]
async fn main() -> Result<()> {
Expand All @@ -22,7 +22,7 @@ async fn main() -> Result<()> {
}));

app.at("/")
.get(|_req: Request<_>| async { Ok(Body::from_file("./does-not-exist").await?) });
.get(|_, _| async { Ok(Body::from_file("./does-not-exist").await?) });

app.listen("127.0.0.1:8080").await?;

Expand Down
6 changes: 3 additions & 3 deletions examples/fib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use tide::Request;
use tide::{Request, State};

fn fib(n: usize) -> usize {
if n == 0 || n == 1 {
Expand All @@ -8,9 +8,9 @@ fn fib(n: usize) -> usize {
}
}

async fn fibsum(req: Request<()>) -> tide::Result<String> {
async fn fibsum(req: Request, _state: State<()>) -> tide::Result<String> {
use std::time::Instant;
let n: usize = req.param("n").unwrap_or(0);
let n: usize = req.param("n")?.parse().unwrap_or(0);
// Start a stopwatch
let start = Instant::now();
// Compute the nth number in the fibonacci sequence
Expand Down
9 changes: 6 additions & 3 deletions examples/graphql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ lazy_static! {
static ref SCHEMA: Schema = Schema::new(QueryRoot {}, MutationRoot {});
}

async fn handle_graphql(mut request: Request<State>) -> tide::Result {
async fn handle_graphql(mut request: Request, state: tide::State<State>) -> tide::Result {
let query: GraphQLRequest = request.body_json().await?;
let response = query.execute(&SCHEMA, request.state());
let response = query.execute(&SCHEMA, &state);
let status = if response.is_ok() {
StatusCode::Ok
} else {
Expand All @@ -88,7 +88,10 @@ async fn handle_graphql(mut request: Request<State>) -> tide::Result {
.build())
}

async fn handle_graphiql(_: Request<State>) -> tide::Result<impl Into<Response>> {
async fn handle_graphiql(
_: Request,
_state: tide::State<State>,
) -> tide::Result<impl Into<Response>> {
Ok(Response::builder(200)
.body(graphiql::graphiql_source("/graphql"))
.content_type(mime::HTML))
Expand Down
2 changes: 1 addition & 1 deletion examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
async fn main() -> Result<(), std::io::Error> {
tide::log::start();
let mut app = tide::new();
app.at("/").get(|_| async { Ok("Hello, world!") });
app.at("/").get(|_, _| async { Ok("Hello, world!") });
app.listen("127.0.0.1:8080").await?;
Ok(())
}
4 changes: 2 additions & 2 deletions examples/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async fn main() -> tide::Result<()> {
tide::log::start();
let mut app = tide::new();

app.at("/submit").post(|mut req: Request<()>| async move {
app.at("/submit").post(|mut req: Request, _| async move {
let cat: Cat = req.body_json().await?;
println!("cat name: {}", cat.name);

Expand All @@ -23,7 +23,7 @@ async fn main() -> tide::Result<()> {
Ok(Body::from_json(&cat)?)
});

app.at("/animals").get(|_| async {
app.at("/animals").get(|_, _| async {
Ok(json!({
"meta": { "count": 2 },
"animals": [
Expand Down
Loading