# Getting Started

This guide assumes you have a basic knowledge of rust. No knowledge of thruster or the web in general is necessary!

### Project Setup

Create a new binary rust project using cargo:

```bash
mkdir carrier-pigeon
cd carrier-pigeon
cargo init --bin
```

Open up the newly generated `Cargo.toml` and add some dependencies for thruster, as well as it's preferred async runtime, tokio.

```toml
[package]
name = "carrier-pigeon" # Get it? Because carrier pigeons carried secrets? eh?
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# ADD THIS PART
env_logger = "0.7.1"
log = "0.4"
thruster = { version = "1.3.0", features = ["hyper_server"] }
tokio = { version = "1.6", features = ["rt", "rt-multi-thread", "macros"] }
```

{% hint style="info" %}
Note that version 1.3.0 is not *yet* released, but will be in the near future. If you're using this guide before it has been released, then replace the `version = "1.3.0"` with `git = "https://github.com/thruster-rs/thruster"`.
{% endhint %}

Here we've added thruster itself (along with a backend server, which we won't cover here) and tokio which is an async runtime for rust that allows thruster to run lots of things efficiently.

Now let's make a super-simple app to make sure everything is working. In `src/main.rs`, change the contents to look like this:

```rust
// 1
use log::info;
use thruster::{
    context::typed_hyper_context::TypedHyperContext,
    hyper_server::HyperServer,
    m,
    middleware_fn, App, HyperRequest, MiddlewareNext, MiddlewareResult, ThrusterServer,
};

// 2
type Ctx = TypedHyperContext<RequestConfig>;

// 3
#[derive(Default)]
struct ServerConfig {}

#[derive(Default)]
struct RequestConfig {}

// 4
fn generate_context(request: HyperRequest, _state: &ServerConfig, _path: &str) -> Ctx {
    Ctx::new(
        request,
        RequestConfig {},
    )
}

// 5
#[middleware_fn]
async fn hello(mut context: Ctx, _next: MiddlewareNext<Ctx>) -> MiddlewareResult<Ctx> {
    context.body("Hello, world!");

    Ok(context)
}

#[tokio::main]
async fn main() {
    env_logger::init();
    info!("Starting server...");

    // 6
    let app = App::<HyperRequest, Ctx, ServerConfig>::create(
        generate_context,
        ServerConfig {},
    )
    // 7
    .get("/hello", m![hello]);

    // 8
    let server = HyperServer::new(app);
    server.build("0.0.0.0", 4321).await;
}

```

Let's break down what we have here (the comments align with the points):

1. All the imports for thruster, not super important but worth noting that we're using a `TypedHyperContext` here. I'll explain why in a few points.
2. It's often convenient to just alias our context type, because we use it a LOT (literally every middleware function.)
3. `ServerConfig` and `RequestConfig` aren't important now, but will be super important later. `ServerConfig` will basically hold the shared state of the server, while `RequestConfig` will hold all of the request-specific pieces that you define. Authentication results are commonly stored in the `RequestConfig`.
4. This function is the backbone of thruster. It's important that this function be nice and efficient because of that. The `generate_context` function takes a request and turns it into a `Context` that's then passed through all of the handling middleware. It also has references to the shared context and path of the request just in case it's useful for the context object. Commonly, this is how references to a database pool are passed to middleware functions.
5. A simple middleware function that sets the body of the response to "Hello, world!". Note that this function doesn't use the `next` function. This means that even if there's other middleware after it, it won't be called. That's what `next` is -- a convenient wrapper to call the "next" function in the chain of middleware.
6. This is how we create an app. We have to tell the app what the server config looks like, and how to generate a context.
7. This is bread and butter of thruster. It's middleware chains! the `get` represents the relevant verb, and the `m!` macro is all of the middleware to call when the route requested. `m!` takes a comma separated list of functions.
8. Thruster is a few pieces, but its router is detached from the actual TCP handling. This means that we can use super optimized or highly featured libraries like Hyper or Actix to do heavy lifting for us! This example will use hyper, so we make a `HyperServer` and pass that `app` to it to serve.

Now run the program!

```
cargo run
```

If you check out `http://localhost:4321/hello` you should see our "Hello, world!" message -- nice!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mertz.gitbook.io/thruster/building-a-cli-secret-sharer/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
