REST API 및 Rust+Warp 3:
Next in line is the
GET
method, which means we'll see parameter handling and (finally) deal with this HashSet thing.
그래서 "심심한 토론에 시간을 낭비하지 말자!"
곡속 3, 이렇게!
The code for this part is available .
우선, 나는 반서열화
GET
를 되돌릴 수 있도록 다른 의존항이 필요하다. 그래서 나는 Cargo.toml
파일을 변경했다.serde_json = "1.0"
그리고 바꿀 때가 됐어요try_list()
.우리가 지난번에 만났을 때 이 테스트는 하나request()
와 하나assert_eq!
뿐이었다.나는 두 가지를 보충했다.POST
. (나는 호출할 수 있었는데db.lock().await.insert()
다른 곳에서 테스트를 했기 때문에 이 단축키를 사용할 수 있다).use std::collections::HashSet;
#[tokio::test]
async fn try_list() {
use std::str;
use serde_json;
let simulation1 = models::Simulation{
id: 1,
name: String::from("The Big Goodbye"),
};
let simulation2 = models::Simulation{
id: 2,
name: String::from("Bride Of Chaotica!"),
};
let db = models::new_db();
db.lock().await.insert(simulation1.clone());
db.lock().await.insert(simulation2.clone());
let api = filters::list_sims(db);
let response = request()
.method("GET")
.path("/holodeck")
.reply(&api)
.await;
let result: Vec<u8> = response.into_body().into_iter().collect();
let result = str::from_utf8(&result).unwrap();
let result: HashSet<models::Simulation> = serde_json::from_str(result).unwrap();
assert_eq!(models::get_simulation(&result, 1).unwrap(), &simulation1);
assert_eq!(models::get_simulation(&result, 2).unwrap(), &simulation2);
let response = request()
.method("GET")
.path("/holodeck/2")
.reply(&api)
.await;
let result: Vec<u8> = response.into_body().into_iter().collect();
let result = str::from_utf8(&result).unwrap();
let result: HashSet<models::Simulation> = serde_json::from_str(result).unwrap();
assert_eq!(result.len(),1);
assert_eq!(models::get_simulation(&result, 2).unwrap(), &simulation2);
}
내가 설명할 만한 첫 번째 일은 lock()
이다.std::sync::Mutex
는 호 안의 내용을 제시했는데 이 예에서 하나를 되돌려준다Future.왜?우리가 사용하는 것은 tokio::sync::Mutex
이 아니라 unwrap()
이기 때문에 전자의 비동기적인 실현이다.이것이 바로 우리가 await
가 아니라 filters::list_sims()
인 이유이다suspend execution until the result of the Future is ready.그런 다음
serde_json::from_str()
이제 HTTP 바디에서 데이터를 반환하는 매개변수가 생성됩니다.요청이 변하지 않은 후에 세 줄 바이트로 jibber jabber를 처리합니다.
Bytes는 WarpRequestBuilder가 HTML 본문 내용을 처리하는 형식입니다.그것은 마치 [u8](즉 원시 u8의 수조)처럼 보이지만, 처리하기에는 좀 고통스럽다. 그러나 나는 그것으로 하는 일은 매우 간단하다.
\\ This code is not in the project!
struct Example {
id: u64,
name: String,
}
type Impossible = HashMap<Example>;
내가 해시맵처럼 struct(쿨한 아이들이 205행에서 Vectorhere를 사용하는 것처럼)를 사용하지 않고 serde
를 사용하면 얻을 수 있다.복잡하다.그럼에도 불구하고 해시집중에 구조를 붙이고 싶은 또 다른 이유는 내 유형에 특성을 실현할 수 있는 기회를 주기 때문이다.
이러한 특징을 깊이 있게 연구하기 전에 나는 테스트의 마지막 부분을 설명하고 싶다(이것은 다른 테스트일 것이다. 그러나 이 예는 이미 너무 크다).
GET
방법은 세 가지 다른 사용 방식이 있다./holodeck
/holodeck/:id
/holodeck/?search=query
request()
사용 경로/holodeck/2
는 두 번째 사례를 덮어쓰기 위해 작성된 것이다.나는 세 번째를 개발하지 못했다.대담하게 특성을 실현하다
HashSet 요소를 다른 요소와 비교하면 모든 컨텐트가 비교됩니다.만약 네가 키 값이 구조에 맞다면 좋지 않을 것이다.상기 이유로 저는 HashMap을 사용하고 싶지 않기 때문에 이런 행동을 바꾸고 id만 비교하는 것을 해야 합니다.
우선, 나는
Hash
와 Hasher
를 가져왔고, 그리고 나는 Eq
, PartialEq
와 Hash
를 삭제했다. 그러면 나는 스스로 그것을 실현할 수 있다.구현 프로세스는 다음과 같습니다.use std::hash::{Hash, Hasher};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Simulation {
pub id: u64,
pub name: String,
}
impl PartialEq for Simulation{
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for Simulation {}
impl Hash for Simulation{
fn hash<H: Hasher>(&self, state: &mut H){
self.id.hash(state);
}
}
어떻게 하는지 내가 어떻게 알아?나는 단지 서류에 적힌 대로 "How can I implement Eq?" 했을 뿐이다.네, 녹슨 의사는 아주 좋아요.그럼 잡채는요?같은 일.근데 재밌는 건 내가 왜 이러는지.해시 집합 수요Hash 특성, 해시 특성 요구:
k1 == k2 -> hash(k1) == hash(k2)
이것은 비교의 값이 같으면 그들의 하쉬 값도 반드시 같아야 한다는 것을 의미한다. 이것은 PartialEq
과Eq
가 실현된 후에 성립되지 않는다. 왜냐하면 이 두 값이 모두 하쉬와 비교되고 직접적인 비교는 관심만 있기 때문이다id
.99% chance that I am wrong, but I think it should not be an implication (→), but a biconditional (↔), because the way it stands if
k1 == k2
is false andhash(k1) == hash(k2)
is true, the implication's result is still true. But I am not a trained computer scientist and I am not sure this uses first-order logic notation. Let me know in the comments if you do.
내가 산열 실현 아래에서 한 마지막 보충은 다음과 같다.
pub fn get_simulation<'a>(sims: &'a HashSet<Simulation>, id: u64) -> Option<&'a Simulation>{
sims.get(&Simulation{
id,
name: String::new(),
})
}
비록 id
등의 방법을 사용할 때 비교에 사용되는 유일한 관련 필드는 get()
이지만 우리는 전체 구조를 전달해야 하기 때문에 나는 get_simulation()
를 만들어서 그것을 대체했다.네, 돌아오는 방법
GET
입니다.법외에서 소요하다.
처리
GET
방법의 함수는 현재 결과를 얻을 수 있는 해시 집합과 사용할 수 있는 인자 두 개의 추가 정보를 처리해야 한다.pub fn list_sims(db: models::Db) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
let db_map = warp::any()
.map(move || db.clone());
let opt = warp::path::param::<u64>()
.map(Some)
.or_else(|_| async {
// Ok(None)
Ok::<(Option<u64>,), std::convert::Infallible>((None,))
});
warp::path!("holodeck" / ..)
.and(opt)
.and(warp::path::end())
.and(db_map)
.and_then(handlers::handle_list_sims)
}
opt
는 보낼 수 있는 선택할 수 있는 매개 변수를 나타낸다.그것은 매개 변수를 얻어 Option
(즉 Some
로 비추었다.제공되지 않은 경우 or_else()
반환None
화async
가 있는 이유는 or_else()
returns a TryFuture 때문이다.우리가 실제로 되돌아온
path
는 이것opt
을 포함하고 우리db_bap
를 포함하는 방식과 같다./ ..
와 path!
는 매크로에 추가하지 말라고 end()
했다. 그러면 내가 추가할 수 있다opt
.이것이 바로 머지않아 수첩end()
이 나올 수 있는 이유다.I didn't found this solution in the docs or in the examples. Actually, for some reason, most tutorials omit
GET
parameters. They either just list everything or use query. I found one tutorial that implemented this, but they did so by creating two filters and two handlers. It didn't felt ok, and I knew there should be a solution and that the problem was probably my searching skills; so I asked for help in warp's discord channel, and the nice gentleman jxs pointed me to the solution you saw above.
다음 단계는 복구 프로세서입니다.
pub async fn handle_list_sims(param: u64, db: models::Db) -> Result<impl warp::Reply, Infallible> {
let mut result = db.lock().await.clone();
if param > 0 {
result.retain(|k| k.id == param);
};
Ok(warp::reply::json(&result))
}
그것은 더 이상 매튜 맥콘나 한들러 (Matthew McConaughey handler) 가 아니지만, 여전히 매우 간단하다.나는 retain
대신 get_simulation()
을 사용합니다. 왜냐하면 이것은 HashSet을 되돌려주기 때문입니다. (get은 나에게 models::Simulation
이것은 바로 처리 프로그램이 되돌려야 하는 것입니다.$ cargo test
running 3 tests
test tests::try_create ... ok
test tests::try_create_duplicates ... ok
test tests::try_list ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
다음 회'왜곡과의 교전'에서...
우리는 실현
PUT
과 DELETE
방법을 통해 실현할 것이다.🖖
Reference
이 문제에 관하여(REST API 및 Rust+Warp 3:), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rogertorres/rest-api-with-rust-warp-3-get-4nll텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)