如何从另一个文件调用函数并在网络中获取

How to call a function from another file and fetch in web

我是 Rust 的新手,但我仍在学习。有一个带有 main.rs 和 routes.rs 的 rust 应用程序。 main.rs 文件有服务器配置,routes.rs 有带路径的方法。

main.rs

#[macro_use]
extern crate log;

use actix_web::{App, HttpServer};
use dotenv::dotenv;
use listenfd::ListenFd;
use std::env;

mod search;

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    dotenv().ok();
    env_logger::init();

    let mut listenfd = ListenFd::from_env();
    let mut server = HttpServer::new(|| 
        App::new()
            .configure(search::init_routes)
    );

    server = match listenfd.take_tcp_listener(0)? {
        Some(listener) => server.listen(listener)?,
        None => {
            let host = env::var("HOST").expect("Host not set");
            let port = env::var("PORT").expect("Port not set");
            server.bind(format!("{}:{}", host, port))?
        }
    };

    info!("Starting server");
    server.run().await
}

routes.rs

use crate::search::User;
use actix_web::{get, post, put, delete, web, HttpResponse, Responder};
use serde_json::json;
extern crate reqwest;
extern crate serde;
use reqwest::Error;
use serde::{Deserialize};
use rocket_contrib::json::Json;
use serde_json::Value;
// mod bargainfindermax;

#[get("/users")]
async fn find_all() -> impl Responder {
    HttpResponse::Ok().json(
        vec![
            User { id: 1, email: "tore@cloudmaker.dev".to_string() },
            User { id: 2, email: "tore@cloudmaker.dev".to_string() },
        ]
    )
}

pub fn init_routes(cfg: &mut web::ServiceConfig) {
    cfg.service(find_all);
}

现在我想要的是使用另一个单独的 rs 文件 (fetch_test.rs) 中的方法获取 API 并将其路由到 routes.rs 文件中。然后我想通过 运行 该路由路径 (link) 从 Web 浏览器获得响应。

我该如何做这些事情??我到处搜索,但没有找到任何帮助。有时我也不理解一些文档。

**更新。

fetch_test.rs

extern crate reqwest;
use hyper::header::{Headers, Authorization, Basic, ContentType};

pub fn authenticate() -> String {

fn construct_headers() -> Headers {
    let mut headers = Headers::new();
    headers.set(
        Authorization(
            Basic {
                username: "HI:ABGTYH".to_owned(),
                password: Some("%8YHT".to_owned())
            }
        )
     );
    headers.set(ContentType::form_url_encoded());
    headers
}

let client = reqwest::Client::new();
let resz = client.post("https://api.test.com/auth/token")
    .headers(construct_headers())
    .body("grant_type=client_credentials")
    .json(&map)
    .send()
    .await?;

}

错误。


   Compiling sabre-actix-kist v0.1.0 (E:\wamp64\www\BukFlightsNewLevel\flights\APIs\sabre-actix-kist)
error[E0425]: cannot find value `map` in this scope
  --> src\search\routes\common.rs:28:12
   |
28 |     .json(&map)
   |            ^^^ not found in this scope

error[E0728]: `await` is only allowed inside `async` functions and blocks
  --> src\search\routes\common.rs:25:12
   |
4  |   pub fn authenticate() -> String {
   |          ------------ this is not `async`
...
25 |   let resz = client.post("https://api-crt.cert.havail.sabre.com/v2/auth/token")
   |  ____________^
26 | |     .headers(construct_headers())
27 | |     .body("grant_type=client_credentials")
28 | |     .json(&map)
29 | |     .send()
30 | |     .await?;
   | |__________^ only allowed inside `async` functions and blocks

error[E0277]: the trait bound `std::result::Result<search::routes::reqwest::Response, search::routes::reqwest::Error>: std::future::Future` is not satisfied
  --> src\search\routes\common.rs:25:12
   |
25 |   let resz = client.post("https://api-crt.cert.havail.sabre.com/v2/auth/token")
   |  ____________^
26 | |     .headers(construct_headers())
27 | |     .body("grant_type=client_credentials")
28 | |     .json(&map)
29 | |     .send()
30 | |     .await?;
   | |__________^ the trait `std::future::Future` is not implemented for `std::result::Result<search::routes::reqwest::Response, search::routes::reqwest::Error>`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src\search\routes\common.rs:25:12
   |
4  |  / pub fn authenticate() -> String {
5  |  |
6  |  |     let res = reqwest::get("http://api.github.com/users")
7  |  | .expect("Couldnt")
...   |
25 |  | let resz = client.post("https://api-crt.cert.havail.sabre.com/v2/auth/token")
   |  |____________^
26 | ||     .headers(construct_headers())
27 | ||     .body("grant_type=client_credentials")
28 | ||     .json(&map)
29 | ||     .send()
30 | ||     .await?;
   | ||___________^ cannot use the `?` operator in a function that returns `std::string::String`
31 |  |
32 |  | }
   |  |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `std::ops::Try` is not implemented for `std::string::String`
   = note: required by `std::ops::Try::from_error`

error[E0308]: mismatched types
 --> src\search\routes\common.rs:4:26
  |
4 | pub fn authenticate() -> String {
  |        ------------      ^^^^^^ expected struct `std::string::String`, found `()`
  |        |
  |        implicitly returns `()` as its body has no tail or `return` expression

**再次更新。

extern crate reqwest;
use hyper::header::{Headers, Authorization, Basic, ContentType};

fn construct_headers() -> Headers {
    let mut headers = Headers::new();
    headers.set(
        Authorization(
            Basic {
                username: "HI:ABGTYH".to_owned(),
                password: Some("%8YHT".to_owned())
            }
        )
     );
    headers.set(ContentType::form_url_encoded());
    headers
}

pub async fn authenticate() -> Result<String, reqwest::Error> {

let client = reqwest::Client::new();
let resz = client.post("https://api.test.com/auth/token")
    .headers(construct_headers())
    .body("grant_type=client_credentials")
    .json(&map)
    .send()
    .await?;

}

**新错误。

error[E0425]: cannot find value `map` in this scope
  --> src\search\routes\common.rs:24:12
   |
24 |     .json(&map)
   |            ^^^ not found in this scope

error[E0277]: the trait bound `impl std::future::Future: search::routes::serde::Serialize` is not satisfied
  --> src\search\routes.rs:24:29
   |
24 |     HttpResponse::Ok().json(set_token)
   |                             ^^^^^^^^^ the trait `search::routes::serde::Serialize` is not implemented for `impl std::future::Future`

error[E0308]: mismatched types
  --> src\search\routes\common.rs:22:14
   |
22 |     .headers(construct_headers())
   |              ^^^^^^^^^^^^^^^^^^^ expected struct `search::routes::reqwest::header::HeaderMap`, found struct `hyper::header::Headers`
   |
   = note: expected struct `search::routes::reqwest::header::HeaderMap`
              found struct `hyper::header::Headers`

error[E0599]: no method named `json` found for struct `search::routes::reqwest::RequestBuilder` in the current scope
  --> src\search\routes\common.rs:24:6
   |
24 |     .json(&map)
   |      ^^^^ method not found in `search::routes::reqwest::RequestBuilder`

error[E0308]: mismatched types
  --> src\search\routes\common.rs:18:63
   |
18 |   pub async fn authenticate() -> Result<String, reqwest::Error> {
   |  _______________________________________________________________^
19 | |
20 | | let client = reqwest::Client::new();
21 | | let resz = client.post("https://api.test.com/auth/token")
...  |
27 | |
28 | | }
   | |_^ expected enum `std::result::Result`, found `()`
   |
   = note:   expected enum `std::result::Result<std::string::String, search::routes::reqwest::Error>`
           found unit type `()`

我可以澄清一下你的问题吗?据我了解,您已经知道如何使用另一个文件中的函数。您是否需要知道如何发出 API 请求并将请求结果作为响应传递?

首先,您需要使用例如 reqwest lib:

创建 fetch_test.rs
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .json(&map)
    .send()
    .await?;
  1. 映射结果或按原样传递。

  2. Return 结果 routes.rs:HttpResponse::Ok().json(res)

希望对你有所帮助