Giter VIP home page Giter VIP logo

actix-website's Introduction

Actix Website

Getting Started

Building the website depends on Docusaurus, you must have npm or yarn installed. You can run the site locally with:

git clone https://github.com/actix/actix-website.git
cd actix-website
npm install  # or yarn install
npm start  # or yarn start

Then visit http://localhost:3000.

Updating diagrams

Diagrams are located under /static/img/diagrams/ and built with Mermaid CLI.

For instance to edit connection_overview diagram:

cd static/img/diagrams
vi connection_overview.mmd
# Compile diagrams:
mmdc -i connection_overview.mmd -o connection_overview.svg

License

This site is licensed under either of

actix-website's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

actix-website's Issues

Update the documentation to fit with actix-web v3

I recently updated the examples via #132, but some examples and the explanation is still on v1 or v0.x (to make matters worse, some examples' explanation is incorrect.). We should update the documentation for newcomers.

Clarify the use of actix-rt

In the Getting Started page we say:

If you want to use the #[actix_rt::main] macro

I am yet to see any alternative to the use of #[actix_rt::main] macro. If it is there it is not discussed in the guide. It will be easier for the reader if actix_rt is added as dependency right in the beginning instead of presenting it as a personal choice for the reader.

Add "- Actix" to the end of all page titles

Currently, I have the Actix website's landing page open in a tab in my Tree Style Tab sidebar as the root of a tree of tabs I use as a "TODO: Try rewriting one of my small web projects in Rust using Actix"... but it makes for a very unhelpful tab title, because it just says "Welcome" and I have a lot of tabs.

It's good practice to include the site/project title in each page title, so it would be "Welcome - Actix" in that case.

Directory custom 404 Not Found response

Hello,
When a file is not available in StaticFiles actix-web automatically shows 404 error without body, i want to show custom error but default_handler not working.

            .handler(
                "/static",
                actix_web::fs::StaticFiles::new("./static/")
                    .default_handler(p404)
                    .index_file("index.html"),
            )

fn p404(req: actix_web::HttpRequest) -> Result<actix_web::HttpResponse, actix_web::Error> {
    println!("{:?}lll", req);
    Ok(actix_web::HttpResponse::NotFound()
        .content_type("text/plain")
        .body("Not Found"))
}

Why is it mostly about actix-web?

I expected the main and the only one official website about actix framework to contain great explanation of it, examples, docs, both, about actix and actix-web, but it is only about actix-web it seems. Why is that?

Update doc example of actix middleware

Hi,

since v2 this middleware documentation example won't compile anymore due to lack of Req type declaration: https://actix.rs/docs/middleware/

I've been fiddling around with it to make my middleware compatible, but couldn't figure this one out:

impl<S, B> Transform<S, B> for MyMiddleware
where
    S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{

the compiler complains about
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
because

wrong number of type arguments: expected 1, found 0
expected 1 type argument

actix-rt dependencies to use the macro

Hi everyone,
i'm upgrading to v2 and i saw the new macro in the updated documentation :
#[actix_rt::main]
By adding this i got the following error :
failed to resolve: use of undeclared type or module actix_rt

I think the documentation should mention somewhere that the developer must add actix-rt in his cargo.toml :
actix-rt = "1.0.0"

Logo is unbalanced

Tossed up where to file this, settled on here. This is a somewhat lighthearted report, but nonetheless a serious issue for the two or three of us who care about such matters. ☺

The Actix logo is not balanced. If you cut it in metal and used it for the sprocket on a bicycle, it would fail dismally.

This is probably most easily demonstrated by supercharging the spinning of the logo on the website:

.navbar-brand img {
	/* The forties are for forty teeth, the 60 for 60fps. */
	animation: spin-logo calc(40s/60) steps(40) infinite;
	/* While we’re at it, let’s make it as big as we can. */
	width: 100vmin;
	height: auto;
	top: calc(50vh - 50vmin);
	left: calc(50vw - 50vmin);
	position: fixed;
	z-index: 1;
	/* You might like to play around with this too, to mitigate some of the image centrepoint unbalancedness: */
	/* transform-origin: 49% 50%; */
}

As you observe, the image is not centred properly, and the teeth are irregularly cut because they’re not aligned with the rest.

The logo should have a fixed centre point about which it rotates, rotational symmetry on its teeth (40-way if it must have 40 teeth—for reference, the Rust logo has 32, and I recommend 48 for Actix to factor neatly into the three-way rotational symmetry), and three-way rotational symmetry on the inner portion.

I’m willing to produce a new, mathematically-sound logo if you want (my approach on the teeth is to use Inkscape’s Pattern Along Path live path effect). I still won’t guarantee it will work as a sprocket, especially if it stays fairly similar in the tooth design. Is there an SVG source for the current logo, for mild convenience? (I observe logo.afdesign, but I have nothing that can open that file type.)

HTTP2 impl FromRequest for HttpRequest

Comparing to HTTP/1.1, when I am using HTTP/2
I am losing header "host:". It looks very strange and very suspicious.
I could not found the answer to my question. Can you please help me and comment on the issue?
Thank you very much

What can we do to prepare the site for multiple languages?

I think we could have a lang directory within content/docs with a new directory for each language.

 content/
    lang/
       fr/
       pt_br/
          application.md // all files translated for each language

In the sequence, it would be nice to have some language selector in the header, already based on the existing lang directories.

And to display the languages, I imagine that we will need to customize the layouts/code so that it renders the Content based on some URL parameter, for example.

https://actix.rs/docs/getting-started?lang=fr or https://actix.rs/docs/fr/getting-started/.

I don't know if it is a good way, they are just ideas so that we can simplify the process in the long run.

Scoped Routes Example

I've put together a 2-tier scoped routes example that I'd like to pass by the group before submitting it as a PR. Usually, these examples exclude certain parts, for brevity. I assume the actual handler functions would be cut from the PR unless others believe they would be useful so as to have an example that actually compiles.

I don't like having to add a trailing forward slash for my gets. I thought actix handled this automatically?

Thoughts?

extern crate actix;
extern crate actix_web;
extern crate serde;
#[macro_use] extern crate serde_derive;
use actix_web::{server, App, HttpRequest, Responder, http::Method, Path};



fn main() {
	// A Project consists of tasks:
	// 		/project/{project_id}/task/{task}
	//
    let sys = actix::System::new("scope_example");

    // Start http server
    server::new(|| {
    	App::new()
        .scope("/project", |proj_scope| {
			proj_scope
			.resource("/", |r| { 
				r.method(Method::GET)
				  .f(get_projects);
				r.method(Method::POST)
				  .f(create_project)})
			.resource("/{project_id}", |r| { 
				  r.method(Method::PUT)
				   .with(update_project);
				  r.method(Method::DELETE)
				   .f(delete_project)})
			.nested("/{project_id}/task", |task_scope| {
				task_scope
				.resource("/", |r| {
					r.method(Method::GET)
					.f(get_tasks);
					r.method(Method::POST)
					.f(create_task)})
				.resource("/{task_id}", |r| { 
					r.method(Method::PUT)
					.with(update_task);
					r.method(Method::DELETE)
					.with(delete_task)})})})
	})
    .bind("127.0.0.1:8080").unwrap()
    .start();

    println!("Started http server: 127.0.0.1:8080");
    let _ = sys.run();
}

#[derive(Debug, Deserialize)]
struct PathInfo {
	project_id: String,
	task_id: Option<String>,
}

fn get_projects(req: HttpRequest) -> impl Responder {
	"get_projects".to_string() 
}
fn create_project(req: HttpRequest) -> impl Responder {
	"create_project".to_string() 
}
fn update_project(path: Path<PathInfo>) -> impl Responder { 
	println!("project_id: {:?}, task_id: {:?}", path.project_id, path.task_id);
	"update_project".to_string() 
}
fn delete_project(req: HttpRequest) -> impl Responder {
	"delete_project".to_string() 
}

fn get_tasks(req: HttpRequest) -> impl Responder {
	"get_tasks".to_string() 
}
fn create_task(req: HttpRequest) -> impl Responder {
	"create_task".to_string() 
}
fn update_task(path: Path<PathInfo>) -> impl Responder {
	println!("project_id: {:?}, task_id: {:?}", path.project_id, path.task_id);
	"update_task".to_string()
}
fn delete_task(path: Path<PathInfo>) -> impl Responder {
	println!("project_id: {:?}, task_id: {:?}", path.project_id, path.task_id);
	"delete_task".to_string() 
}

content/docs/static-files.md contains an incorrect example

For example, the directory example:

use actix_web::{App, fs};

fn main() {
    App::new()
        .handler(
            "/static",
            fs::StaticFiles::new(".")
                .unwrap()
                .show_files_listing())
        .finish();
}

Needs to actually run a server to do anything:

use actix_web::{App, fs, server};

fn main() {
    server::new(|| App::new()
        .handler(
            "/static",
            fs::StaticFiles::new(".")
                .unwrap()
                .show_files_listing()))
        .bind("127.0.0.1:8888")
        .expect("Can not bind to port 8888")
        .run()
}

Lots of other examples have the same problem, in various chapters. I sympathize with wanting to keep noise low, but I would argue you also want your examples to either actually do something when run, or not compile.

"App data is not configured, to configure use App::data()" in official document example

Expected Behavior

it should display a counter as expected.

Current Behavior

it display 'App data is not configured, to configure use App::data()' in response

Steps to Reproduce (for bugs)

  1. Copy and paste the last code example in https://actix.rs/docs/extractors/, the Application state extractor section
  2. Hit cargo run.
use actix_web::{web, Responder};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

#[derive(Clone)]
struct AppState {
    count: Arc<AtomicUsize>,
}

async fn show_count(data: web::Data<AppState>) -> impl Responder {
    format!("count: {}", data.count.load(Ordering::Relaxed))
}

async fn add_one(data: web::Data<AppState>) -> impl Responder {
    data.count.fetch_add(1, Ordering::Relaxed);

    format!("count: {}", data.count.load(Ordering::Relaxed))
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{App, HttpServer};

    let data = AppState {
        count: Arc::new(AtomicUsize::new(0)),
    };

    HttpServer::new(move || {
        App::new()
            .app_data(data.clone())
            .route("/", web::to(show_count))
            .route("/add", web::to(add_one))
    })
    .bind("127.0.0.1:8088")?
    .run()
    .await
}

Possible Solution

changing .app_data to .data makes it work but data can't be shared between threads.

Your Environment

win10x64 1909

  • Rust Version (I.e, output of rustc -V): rustc 1.41.0 (5e1a79984 2020-01-27)
  • Actix Web Version:

cargo.toml

[package]
name = "test-actix"
version = "0.1.0"
authors = [""]
edition = "2018"

[dependencies]
actix-web = "2.0"
actix-rt = "1.0"
listenfd = "0.3"
serde = "1.0.105"

incorrect code in handlers section of documents.

I briefly looked for a way to create a PR for this however I am uncertain how or where the examples are being pulled from in the docs.

at the following location: https://actix.rs/docs/handlers/ (Streaming response body)

There is the following example:

use actix_web::{get, App, Error, HttpResponse, HttpServer};
use bytes::Bytes;
use futures::future::ok;
use futures::stream::once;

#[get("/stream")]
async fn stream() -> HttpResponse {
    let body = once(ok::<_, Error>(Bytes::from_static(b"test")));

    HttpResponse::Ok()
        .content_type("application/json")
        .streaming(body)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().service(stream))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

I believe that Bytes should be imported from the following location:

use actix_web::web::Bytes;

When first going through this I assumed that I was meant to add this as a dependency. However this will give you an issue of having two different versions of the same type.

Could someone update the docs or point me in the direction where I can make a PR?

lowercase 'rust' in title

Is the webpage title and subheading supposed to have a lowercase 'rust'?

image

As of right now, Rust is displayed as lowercase. I understand if this is intentional as to maintain all lowercase letters, but I want to make sure it's not a mistake.

Sample is broken

A Static File sample is broken here if I try to compile "# Configuration":

error[E0308]: try expression alternatives have incompatible types
  --> src/main.rs:20:8
   |
20 |     Ok(NamedFile::open_with_config(path, MyConfig)?)
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |        |
   |        expected struct `actix_web::fs::DefaultConfig`, found struct `MyConfig`
   |        help: try wrapping with a success variant: `Ok(NamedFile::open_with_config(path, MyConfig)?)`
   |
   = note: expected type `actix_web::fs::NamedFile<actix_web::fs::DefaultConfig>`
              found type `actix_web::fs::NamedFile<MyConfig>`

the error message is also broken in Rust, see here rust-lang/rust#52537

in /docs/server Usage of actix-rt before introduction.

The example the Server Basics are as follows right now:

use actix_web::{web, App, HttpResponse, HttpServer};

fn main() {
    let sys = actix_rt::System::new("example");

    HttpServer::new(|| {
        App::new().route("/", web::get().to(|| HttpResponse::Ok()))
    })
    .bind("127.0.0.1:8088")
    .unwrap()
    .start();

    let _ = sys.run();
}

This is the first time actix_rt usage comes up. This was my experience:

  1. Thought I might have missed something. went back through the previous tutorials using ctrl-f
  2. Nothing came up, so searched the names of the example folders
  3. Did a google search. Saw that it was in independent crate
  4. went to crates.io - saw it was actix runtime
  5. added as Cargo.toml dependency and used the crate.
  6. It now works.

Unfortunately, I'm using it, even though I don't understand what its purpose is beyond a somewhat educate guess.

I would suggest that the reader be shown what to do, so they don't have to do the same. I also think it might be important to briefly mention the purpose of the runtime, even if it's just "For now, just know that the server needs this runtime. We cover it in more depth in "

I'm not familiar enough with actix to know what a fix might be, hence the lack of PR. I'm keen to participate how I can though

(updated by @JohnTitor, re-formatted)

Review and Partially Revert Chinese Changes to Layouts

@krircc the latest changes you made to the templates make this a mess to maintain and it broke things more than once. I do not want to change too much now but before you do any more changes can we discuss why things are done the way they are?

  1. why do we need to use different baseURLs in the config? This makes multilingual testing really complicated. It spawns multiple hugo servers
  2. why do we need to have chinese stuff in the index layout template? Can we not instead have includes that are language specific?
  3. Do we need this language specific javascript code? It again makes stuff very messy to maintain and it will get even harder if someone wants to add another language

How to separate passing of App closure instance to HttpServer?

I tried the following code to do app separation logic

fn routes() -> impl Fn() -> actix_web::app::App<actix_web::app_service::AppEntry, actix_http::actix_http::Body> {
    || {
        let app = App::new()
            .route("/", web::get().to(greet))
            .route("/{name}", web::get().to(greet));

        return app;
    }
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(routes())
    .bind("127.0.0.1:8088")?
    .run()
    .await
}

But with this compiler is giving me errors-

  Compiling main-example v1.0.0 (/home/bob/code/rust/hello_world)
error[E0433]: failed to resolve: use of undeclared type or module `actix_http`
  --> src/main.rs:17:83
   |
17 | fn routes() -> impl Fn() -> actix_web::app::App<actix_web::app_service::AppEntry, actix_http::actix_http::Body> {
   |                                                                                   ^^^^^^^^^^ use of undeclared type or module `actix_http`

error[E0603]: module `app` is private
  --> src/main.rs:17:40
   |
17 | fn routes() -> impl Fn() -> actix_web::app::App<actix_web::app_service::AppEntry, actix_http::actix_http::Body> {
   |                                        ^^^ this module is private
   |
note: the module `app` is defined here
  --> /home/bob/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-2.0.0/src/lib.rs:81:1
   |
81 | mod app;
   | ^^^^^^^^

error[E0603]: module `app_service` is private
  --> src/main.rs:17:60
   |
17 | fn routes() -> impl Fn() -> actix_web::app::App<actix_web::app_service::AppEntry, actix_http::actix_http::Body> {
   |                                                            ^^^^^^^^^^^ this module is private
   |
note: the module `app_service` is defined here
  --> /home/bob/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-2.0.0/src/lib.rs:82:1
   |
82 | mod app_service;
   | ^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `impl std::ops::Fn<()>: std::clone::Clone` is not satisfied
  --> src/main.rs:29:21
   |
29 |     HttpServer::new(routes())
   |                     ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `impl std::ops::Fn<()>`
   |
   = note: required by `actix_web::server::HttpServer::<F, I, S, B>::new`

error[E0277]: the trait bound `impl std::ops::Fn<()>: std::clone::Clone` is not satisfied
  --> src/main.rs:29:5
   |
29 |     HttpServer::new(routes())
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `impl std::ops::Fn<()>`
   |
   = note: required by `actix_web::server::HttpServer`

So how can I do separation of routes list from the server declaration?

Instruction

Add instruction how to generate side.

I got error from cobalt:

[nikki]:actix-website$ cobalt --version
Cobalt 0.11.0
[nikki]:actix-website$ cobalt serve
[warn]   No _cobalt.yml file found in current directory, using default config.
[warn]   Syntax theme named 'base16-ocean.dark' ignored. Reason: Themes are unsupported in this build.
[info]   Building from "./actix-website/" into "./actix-website/_site"
Error: serve command failed
Caused by: Failed to parse "more.md"
Caused by: unknown field `extends`, expected one of `permalink`, `slug`, `title`, `description`, `excerpt`, `categories`, `excerpt_separator`, `published_date`, `format`, `layout`, `is_draft`, `data` at line 1 column 1

Middleware: Logging example overwrites RUST_LOG env var

After I had copied the logging example from the section about middlewares, I spent some time figuring out why my own logging statements didn't appear in the terminal. The example modifies the RUST_LOG environment variable, so the different values I tried in the shell had no effect. The example code could be modified to use a default value without overwriting the environment.

A question regarding the sample code

...provided here:

I'm wondering how this sample is supposed to work. OK, I see the server is started on a separate thread, but if I run this app, the entire server is torn down again immediately, because nobody stops is from doing so.

So what does this sample give?

use actix_web::{web, App, HttpResponse, HttpServer, rt::System};
use std::sync::mpsc;
use std::thread;

#[actix_web::main]
async fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let sys = System::new("http-server");

        let srv = HttpServer::new(|| {
            App::new().route("/", web::get().to(|| HttpResponse::Ok()))
        })
        .bind("127.0.0.1:8080")?
        .shutdown_timeout(60) // <- Set shutdown timeout to 60 seconds
        .run();

        let _ = tx.send(srv);
        sys.run()
    });

    let srv = rx.recv().unwrap();

    // pause accepting new connections
    srv.pause().await;
    // resume accepting new connections
    srv.resume().await;
    // stop server
    srv.stop(true).await;
}

Add Option<Extractor> to extractors example

It would be nice to mention the fact that in addition to using the FromRequest::extract method, you can also use the implementation of FromRequest for Option<T: FromRequest> if you have form data that may or may not exist.

You usually don't control the data being submitted, so it's pretty much always better to use Option<web::Form> rather than just having actix return "Content type error" to the user.

Mention web::block() in database doc

I see there were many questions around how to use a sync database API in the GitHub issues and gitter channel. Looks like the easiest and well-accepted method is to use web::block(). But the database documentation still only mention sync actors.

Expected Behavior

It would be nice to mention that web::block() is an option and point the reader to the example code.

Current Behavior

The doc only mentions sync actors, which requires a lot of boilerplate code and people keep asking in gitter or github issues.

Context

I apologize if this is already tracked in other documentation update PR, or web::block() is not that ready yet.

Improve JSON response documentation

JSON is the primary data format for RESTful service today. Yet the JSON response documentation is buried much later in the Responses page. Conversely items like form and multi-part requests that are not idiomatic for web services are surfaced much earlier. I will love to see the material re-organized so that JSON request and response comes earlier.

In addition, the JSON response example uses Result<HttpResponse> as the return type.

async fn index(obj: web::Path<MyObj>) -> Result<HttpResponse> {
    Ok(HttpResponse::Ok().json(MyObj {
        name: obj.name.to_string(),
    }))
}

While this works it is not strongly typed. A better example will be to use strong typing in return.

async fn index(req: HttpRequest) -> Result<web::Json<MyObj>> {
    Ok(web::Json(MyObj {
        name: String::from("Hello"),
    }))
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.