rest API 클라이언트 Golang vs Rust는 어떻게 만듭니까?
rest API 클라이언트 Golang vs Rust는 어떻게 만듭니까?
프로그래밍 언어 전쟁
이봐, 내 친구들, 이 전쟁에 관한 새로운 게시물.
나는 어느 것이 더 좋은지 모르겠지만, 나는 방법을 강구해서 분명히 할 것이다.나는 너희들이 모두 이 시리즈를 좋아하길 바란다.시작!
RESTful API는 HTTP 요청을 사용하여 데이터를 액세스하고 사용하는 응용 프로그램 인터페이스(API)의 아키텍처 스타일입니다.
사람들이 왜 이걸 써요?매번 우리가 마이크로 서비스와 서비스 간에 통신을 해야 할 때, 분명히 다른 통신 방식이 존재하지만, 이것이 가장 유행하기 때문이다.
이 예에서는 Chuck Norris 농담에 대한 API와 단점 간 조작에 대한 정보를 얻을 것입니다.
끝점은 우리가 정보를 얻을 수 있는 URL이다.
Golang/Go
첫 번째 부분은 이 코드를 실행하는 데 필요한 모든 패키지를 가져오는 것입니다.
package main
import (
"encoding/json" // package json implements encoding and decoding of JSON
"fmt" // implements formatted I/O
"io/ioutil" // implements some I/O utility functions
"log" // implements a simple logging package
"math/rand" // implements pseudo-random number generators unsuitable for security-sensitive work
"net/http" // provides HTTP client and server implementations
"time" // provides functionality for measuring and displaying time
"github.com/davecgh/go-spew/spew" // implements a deep pretty printer for Go data structures to aid in debugging.
)
다음 코드는 API 응답의 구조를 조작하는 방법을 정의합니다.type Joke struct {
ID string `json:"id"`
Value string `json:"value"`
Categories []string `json:"categories"`
URL string `json:"url"`
CreatedAt string `json:"created_at"`
IconURL string `json:"icon_url"`
UpdatedAt string `json:"updated_at"`
}
다음 코드는 주 함수입니다. 주 함수임을 기억하십시오. 실행할 입구점이기 때문입니다.주요 기능은 무엇입니까?
내가 시간을 초기화하는 이유는 실행이 얼마나 오래 지속되는지 알기 위해서이다. 다음에 나는 함수 getCategory (스포일러 경보 후에 이 함수를 설명하고 분류를 가져올 것) 를 호출하고 이 정보로 다른 함수 콜 GetChake (여기에서 무슨 일이 일어났는지 알 것) 를 호출한다. 마지막으로, 나는 시간을 계산하고 실행 지속 시간을 출력한다.
func main() {
start := time.Now()
var category = getCategory()
getJoke(category)
elapsed := time.Since(start)
fmt.Printf("Execution lasts: %s\n", elapsed)
}
나는 네가 이 댓글을 좋아하길 바란다. 나는 이렇게 하는 것을 좋아한다.네, 계속하겠습니다.getCategory 함수:
내 HTTP 클라이언트를 시작합니다. 이 클라이언트는 누가 포트나 서비스에서 정보를 얻을 수 있기 때문에 누가 우리에게 우스갯소리를 알려주겠지만, 우선 종류입니다. 그리고 HTTP의 또 다른 방법인 New Request를 사용합니다. 이 방법으로 요청을 보내면, 요청은 무엇입니까?
동사+단점 또는 URL+데이터는 이 예에서 데이터가 필요하지 않지만 Golang에서는 키워드nil을 사용하여 데이터를 보내지 않았음을 나타냅니다.
이 방법은 두 개의 값, 요청, 오류를 되돌려줍니다.
만약 내가 잘못이 없다면, 만약 내가 울 것이 없다면, 나는 계속할 수 있다.
다음에, 나는 클라이언트 호출 방법인 Do withvalue 요청을 사용하고, 두 개의 값,response 또는error를 받는다.
나는 다시 손가락을 깍지 끼고 좋은 소식을 빌었다.
패키지 ioutil에서 바디 응답의 ReadAll 방법을 읽고 두 개의 값을 다시 받았습니다. (알고 있습니다. 알고 있습니다.) 바디 또는 error.
응답하는 방법을 아는 것이 중요하다. 클라이언트(Hoppscotch나 Postman)를 사용하거나 몸을 출력할 수 있다. (fmt.Printf ('%s', body). 다른 방식으로 응답을 표시할 수 있지만, 가장 유행하는 것은 JSON이다.
무슨 뜻[]string, 이것은 데이터 형식이다. 이것은 문자열의 그룹을 나타낸다. 그리고 나는 Unmarshal from JSON의 방법을 사용하여 이 정보를 나타낸다. 이것은 JSON이다. 나는 문자열의 그룹이라는 것을 알고 변수에 넣는다. 나는 문자열의 그룹으로 정의했다. 그러나 이 방법은 하나의 값만 되돌려준다. 만약 오류라면 발생하는 것이 오류가 아니냐?변수 bodyArray는 이런 형식으로 데이터를 가져옵니다.
문자열 그룹의 데이터를 왜 바꾸는지 물어봐도 된다. 왜냐하면 이것은 이 정보를 사용하는 가장 간단한 방법이기 때문이다.
나는 16개의 위치가 있는 그룹을 받았다. 이것은 내가 다른 종류를 나타내는 16개의 문자열을 가지고 있다는 것을 의미하지만, 나는 하나가 필요하다.
내 선택은 이 정보를 무작위로 얻는 것이다. 이를 위해, 나는 방법인 Seed from rand package를 사용해서 매번 실행할 때마다 다른 숫자가 필요하다고 말했다.
마지막으로, 나는 수조에서 값을 되돌려야 한다. 이 방법을 통해, 나는 0과 수조rand 길이 사이의 정수치를 얻을 수 있다.Intn(len(bodyArray).
"BodyArray[10]"와 같은 유사한 컨텐츠를 반환합니다.
func getCategory() string {
client := http.Client{}
request, err := http.NewRequest("GET", "https://api.chucknorris.io/jokes/categories", nil)
if err != nil {
log.Fatal(err)
}
response, err := client.Do(request)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var bodyArray []string
newErr := json.Unmarshal(body, &bodyArray)
if newErr != nil {
log.Fatal(newErr)
}
rand.Seed(time.Now().UnixNano())
return bodyArray[rand.Intn(len(bodyArray))]
}
getJoke 함수:첫 번째 단계는 before 함수와 같고 유일한 차이점은 단점과 응답 형식입니다.
Unmarshal 메서드는 JSON 패키지에서 가져와 바디 응답을 우스갯소리 구조로 변환합니다.
지금은 쓰레기장과 구조를 사용할 때다.좋아, 처음부터 시작할게.
쓰레기장은 단지 유사한 건축물의 아름다움을 보여주기 위한 것이다
{
ID: (string) (len=22) "0wdewlp2tz-mt_upesvrjw",
Value: (string) (len=136) "Chuck Norris does not follow fashion trends, they follow him. But then he turns around and kicks their ass. Nobody follows Chuck Norris.",
Categories: ([]string) (len=1 cap=4) {
(string) (len=7) "fashion"
},
URL: (string) (len=55) "https://api.chucknorris.io/jokes/0wdewlp2tz-mt_upesvrjw",
CreatedAt: (string) (len=26) "2020-01-05 13:42:18.823766",
IconURL: (string) (len=59) "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
UpdatedAt: (string) (len=26) "2020-01-05 13:42:18.823766"
}
그러나 이 구조의 어떤 값을 사용하려면 변수 이름 +를 사용해야 한다.구조 값 이름입니다.예문: 우스갯소리.가치관
func getJoke(category string) {
client := http.Client{}
request, err := http.NewRequest("GET", "https://api.chucknorris.io/jokes/random?category="+category, nil)
if err != nil {
log.Fatal(err)
}
response, err := client.Do(request)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var joke Joke
newErr := json.Unmarshal(body, &joke)
if newErr != nil {
log.Fatal(newErr)
}
spew.Dump(joke)
fmt.Println(joke.Value)
}
이것은 내가 Golang에 있는 모든 코드다.package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"math/rand"
"net/http"
"time"
"github.com/davecgh/go-spew/spew"
)
type Joke struct {
ID string `json:"id"`
Value string `json:"value"`
Categories []string `json:"categories"`
URL string `json:"url"`
CreatedAt string `json:"created_at"`
IconURL string `json:"icon_url"`
UpdatedAt string `json:"updated_at"`
}
func main() {
start := time.Now()
var category = getCategory()
getJoke(category)
elapsed := time.Since(start)
fmt.Printf("Execution lasts: %s\n", elapsed)
}
func getCategory() string {
client := http.Client{}
request, err := http.NewRequest("GET", "https://api.chucknorris.io/jokes/categories", nil)
if err != nil {
log.Fatal(err)
}
response, err := client.Do(request)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var bodyArray []string
newErr := json.Unmarshal(body, &bodyArray)
if newErr != nil {
log.Fatal(newErr)
}
rand.Seed(time.Now().UnixNano())
return bodyArray[rand.Intn(len(bodyArray))]
}
func getJoke(category string) {
client := http.Client{}
request, err := http.NewRequest("GET", "https://api.chucknorris.io/jokes/random?category="+category, nil)
if err != nil {
log.Fatal(err)
}
response, err := client.Do(request)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
var joke Joke
newErr := json.Unmarshal(body, &joke)
if newErr != nil {
log.Fatal(newErr)
}
spew.Dump(joke)
fmt.Println(joke.Value)
}
녹슬다첫 번째 부분은 이 코드를 실행하는 데 필요한 모든 의존항을 추가하는 것입니다.이러한 의존 항목은 Cargo 파일에 추가해야 한다는 점에 유의하십시오.톰
[dependencies]
reqwest = { version = "0.11", features = ["json"] } # provides a convenient, higher-level HTTP Client.
tokio = { version = "1", features = ["full"] } # an event-driven, non-blocking I/O platform for writing asynchronous applications
serde = { version = "1", features = ["derive"] } # framework for serializing and deserializing Rust data structures efficiently and generically.
serde_json = "1.0" # A JSON serialization file format
futures = "0.3" # provides a number of core abstractions for writing asynchronous code
rand = "0.8.4" # provides utilities to generate random numbers
이제 파일 홈 디렉토리로 이동합니다.rs우선, 이 코드를 실행하는 데 필요한 모듈을 호출합니다.
use rand::Rng;
use serde::Deserialize;
use std::time::Instant;
use reqwest::Client;
#[derive] 이것은 하나의 특성을 실현할 수 있다. 이것은 이 줄 다음에 구조를 어떻게 정의하는지 볼 수 있다는 것을 의미한다. 나는 JSON에서 이 정보를 얻어야 한다는 것을 안다. 그래서 이 정보에 대한 반서열화를 실현하기 위해 나는 어떻게 반서열화나 디버깅으로 구성하는지 말해야 한다.따라서 #[derive(Deserialize, Debug)],Deserialize는 구조에서 JSON을 변환할 수 있습니다. Debug는 이 조작부호 {:?}로 변수를 표시할 수 있습니다.
#[derive(Deserialize, Debug)]
struct Joke {
id: String,
value: String,
categories: Vec<String>,
created_at: String,
icon_url: String,
updated_at: String,
url: String,
}
#[tokio::main] 함수는 매크로입니다.이것은 비동기 fnmain () 을 동기 fnmain () 으로 변환합니다. 이 동기 fnmain () 은 실행할 때 실례를 초기화하고 비동기 fnmain 함수를 실행합니다.여기서 tokio에 대한 정보를 더 읽을 수 있습니까?다음 코드는 주 함수입니다. 주 함수임을 기억하십시오. 실행할 입구점이기 때문입니다.
주요 기능은 무엇입니까?
나는 시간을 초기화했는데 왜 이렇게 해야 합니까?다음에 나는 함수 get category를 호출한다. (나는 뒤에서 이 함수를 설명할 것이다. 스포일러 경보, get a category, 마치 Deja bu처럼 보인다.) 그리고 이 정보에 따라 다른 함수 get chake를 호출한다. 마지막으로, 나는 시간을 계산하고 실행 시간을 출력한다.
#[tokio::main]
async fn main() {
let start = Instant::now();
let category = get_category().await;
get_joke(category).await;
let end = start.elapsed();
println!("Execution lasts: {:?}", end);
}
범주 기능을 가져오려면 다음과 같이 하십시오.우선, 나는 함수를 정의하고 반드시 되돌려야 할 데이터 형식을 설명한다.
get who need the endpoint 또는 URL how 매개 변수를 실례화하고 사용한 다음 방법send () 와wait (무엇을 하는지 알아맞힐 수 있습니까?)그리고 열어봐.
녹슨 것을 열어라. 즉, 계산한 결과가 틀리면 당황하고 프로그램을 멈추라는 것이다.더 알고 싶으면Error Handling
그런 다음 JSON 응답을 문자열 벡터로 변환합니다.
범주 응답의 길이를 계산합니다.
검색 지연이 초기화된 루트 로컬 랜덤 생성기, 이 생성기는 시스템에서 피드를 설정합니다.추가info
0과 클래스의 길이에서 문자열을 무작위로 되돌려줍니다.
async fn get_category() -> String {
let res1 = Client::new()
.get("https://api.chucknorris.io/jokes/categories")
.send()
.await
.unwrap();
let categories = res1.json::<Vec<String>>().await.unwrap();
let count = categories.len();
let mut rng = rand::thread_rng();
categories[rng.gen_range(0..count)].to_string()
}
get 농담 기능:첫 번째 단계는 before 함수와 같고 유일한 차이점은 단점과 응답 형식입니다.
형식!는 두 개 이상의 문자열을 결합할 수 있는 매크로입니다.
그리고 저는 JSON 응답을 우스갯소리 구조로 바꿨습니다.
{#?}그리고{?}이것은 단지 그것의 구조를 보여주기 위해서일 뿐, 보기에는 이렇다.
Joke {
id: "6sdvoj-msgi6miv07ekctq",
value: "Chuck Norris is currently suing myspace for taking the name of what he calls everything around you.",
categories: [
"dev",
],
created_at: "2020-01-05 13:42:19.104863",
icon_url: "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
updated_at: "2020-01-05 13:42:19.104863",
url: "https://api.chucknorris.io/jokes/6sdvoj-msgi6miv07ekctq",
}
그러나 이 구조의 어떤 값을 사용하려면 변수 이름 +를 사용해야 한다.구조 값 이름입니다.예문: 우스갯소리.가치 01 명
async fn get_joke(category: String) {
let res1 = Client::new()
.get(format!(
"https://api.chucknorris.io/jokes/random?category={}",
category
))
.send()
.await
.unwrap();
let joke = res1.json::<Joke>().await.unwrap();
println!("{:#?}", joke);
println!("{:?}", joke.value);
}
이것은 나의 모든 코드다.use rand::Rng;
use serde::Deserialize;
use std::time::Instant;
use reqwest::Client;
#[derive(Deserialize, Debug)]
struct Joke {
id: String,
value: String,
categories: Vec<String>,
created_at: String,
icon_url: String,
updated_at: String,
url: String,
}
#[tokio::main]
async fn main() {
let start = Instant::now();
let category = get_categories().await;
get_joke(category).await;
let end = start.elapsed();
println!("Execution lasts: {:?}", end);
}
async fn get_category() -> String {
let res1 = Client::new()
.get("https://api.chucknorris.io/jokes/categories")
.send()
.await
.unwrap();
let categories = res1.json::<Vec<String>>().await.unwrap();
let count = categories.len();
let mut rng = rand::thread_rng();
categories[rng.gen_range(0..count)].to_string()
}
async fn get_joke(category: String) {
let res1 = Client::new()
.get(format!(
"https://api.chucknorris.io/jokes/random?category={}",
category
))
.send()
.await
.unwrap();
let joke = res1.json::<Joke>().await.unwrap();
println!("{:#?}", joke);
println!("{:?}", joke.value);
}
결론구조:
Golang은 엔드포인트에 대한 정보를 가져오고 읽으려면 더 많은 절차가 필요합니다.
Golang은 camelcase 구조를 사용하여 변수와 함수를 정의하지만 Rust는 snake case를 사용합니다.
Golang은 88줄 코드를, Rust는 54에 16줄 카고 코드를 사용했다.toml 파일
지속적
코드는 세그먼트당 5번 실행되며 평균 결과는 다음과 같습니다.
고랑: 3.33초
녹식:4.44s
하지만 누가 더 좋은지 아는 것만으로는 부족하다고 생각한다.
당신은 어떻게 생각합니까?API 클라이언트 및 기타 방법에 대해 더 알고 싶으십니까?
더 알고 싶으면Golang or Rust
나는 네가 나의 댓글을 좋아하고 내가 단지 너와 같은 개발자일 뿐이라는 것을 기억하길 바란다.
Reference
이 문제에 관하여(rest API 클라이언트 Golang vs Rust는 어떻게 만듭니까?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/devlikeyou/how-to-create-a-rest-api-client-golang-vs-rust-1dl7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)