{{ partial "header" . }}

rust's powerful actor system and most fun web framework

## Type Safe

Forget about stringly typed objects, from request to response, everything has types.

## Feature Rich

Actix provides a lot of features out of box. WebSockets, HTTP/2, pipelining etc.

## Extensible

Easily create your own libraries that any Actix application can use.

## Blazingly Fast

Actix is blazingly fast. Check yourself.

{{ highlight `extern crate actix_web; use actix_web::{server, App, HttpRequest, Responder}; fn greet(req: HttpRequest) -> impl Responder { let to = req.match_info().get("name").unwrap_or("World"); format!("Hello {}!", to) } fn main() { server::new(|| { App::new() .resource("/", |r| r.f(greet)) .resource("/{name}", |r| r.f(greet)) }) .bind("127.0.0.1:8000") .expect("Can not bind to port 8000") .run(); }` "rust" "" }}

## Flexible Responders

Handler functions in actix can return a wide range of objects that implement the `Responder` trait. This makes it a breeze to return consistent responses from your APIs.

{{ highlight `#[derive(Serialize)] struct Measurement { temperature: f32, } fn hello_world() -> impl Responder { "Hello World!" } fn current_temperature(_req: HttpRequest) -> impl Responder { Json(Measurement { temperature: 42.3 }) }` "rust" "" }}

## Powerful Extractors

Actix comes with a powerful extractor system that extracts data from the incoming HTTP request and passes it to your view functions. Not only does this make for a convenient API but it also means that your view functions can be synchronous code and still benefit from asynchronous IO handling.

{{ highlight `#[derive(Deserialize)] struct Event { timestamp: f64, kind: String, tags: Vec, } fn capture_event(evt: Json) -> impl Responder { let id = store_event_in_db(evt.timestamp, evt.kind, evt.tags); format!("got event {}", id) }` "rust" "" }}

## Easy Form Handling

Handling multipart/urlencoded form data is easy. Just define a structure that can be deserialized and actix will handle the rest.

{{ highlight `#[derive(Deserialize)] struct Register { username: String, country: String, } fn register(data: Form) -> impl Responder { format!("Hello {} from {}!", data.username, data.country) }` "rust" "" }}

## Request Routing

An actix app comes with a URL routing system that lets you match on URLs and invoke individual handlers. For extra flexibility, scopes can be used.

{{ highlight `fn index(req: HttpRequest) -> impl Responder { "Hello from the index page" } fn hello(path: Path) -> impl Responder { format!("Hello {}!", *path) } fn main() { App::new() .resource("/", |r| r.method(Method::Get).with(index)) .resource("/hello/{name}", |r| r.method(Method::Get).with(hello)) .finish(); }` "rust" "" }}

- flexible responders
- powerful extractors
- easy form handling
- request routing

Rust强大的actor系统和有趣的web框架

## 类型安全

忘记关于字符串类型的对象，从请求到响应，一切都有类型，异步。

## 特性丰富

Actix提供了丰富的特性开箱即用。WebSockets，HTTP/2，流，管道，SSL，异步HTTTP客户端等一应俱全.

## 扩展性强

轻松创建任何基于Actix应用的自己的特色库。

## 速度极快

Actix 具有顶级的速度. Check yourself.

{{ highlight `extern crate actix_web; use actix_web::{http::Method, server, App, Path, Responder}; fn index(info: Path<(u32, String)>) -> impl Responder { format!("Hello {}! id:{}", info.1, info.0) } fn main() { server::new( || App::new() .route("/{id}/{name}/index.html", Method::GET, index)) .bind("127.0.0.1:8080").unwrap() .run(); }` "rust" "" }}

## 灵活的请求响应

Actix中的Handler函数可以返回实现该`Respondert` rait的各种对象。这使得从API返回一致的响应变得轻而易举。

{{ highlight `#[derive(Serialize)] struct Measurement { temperature: f32, } fn hello_world() -> impl Responder { "Hello World!" } fn current_temperature(_req: HttpRequest) -> impl Responder { Json(Measurement { temperature: 42.3 }) }` "rust" "" }}

## 强大的Extractors

Actix提供了一个强大的提取器系统，可以从传入的HTTP请求中提取数据并将其传递给您的视图函数。这不仅可以创建方便的API， 而且还意味着您的视图函数可以是同步代码，并且仍然可以受益于异步IO处理。

{{ highlight `#[derive(Deserialize)] struct Event { timestamp: f64, kind: String, tags: Vec, } fn capture_event(evt: Json) -> impl Responder { let id = store_event_in_db(evt.timestamp, evt.kind, evt.tags); format!("got event {}", id) }` "rust" "" }}

## 轻松处理表单

处理multipart/ urlencoded表单数据很容易。只需定义一个可以反序列化的结构，actix就可以处理剩下的部分。

{{ highlight `#[derive(Deserialize)] struct Register { username: String, country: String, } fn register(data: Form) -> impl Responder { format!("Hello {} from {}!", data.username, data.country) }` "rust" "" }}

## 请求路由

一个actix应用程序带有一个URL路由系统，可以让你在URL上匹配并调用单个处理程序。为了获得额外的灵活性，可以使用域。

{{ highlight `fn index(req: HttpRequest) -> impl Responder { "Hello from the index page" } fn hello(path: Path) -> impl Responder { format!("Hello {}!", *path) } fn main() { App::new() .resource("/", |r| r.method(Method::Get).with(index)) .resource("/hello/{name}", |r| r.method(Method::Get).with(hello)) .finish(); }` "rust" "" }}
{{ partial "footer" . }}