명령줄 인터페이스(CLI)의 활용은 소프트웨어 개발과 시스템 관리 모두에서 없어서는 안 될 중요한 역할을 합니다. 간결하고 직관적인 특징이 있는 이러한 CLI 프로그램은 컴퓨터 시스템과 통신하는 효율적인 수단을 제공하며 자동화, 스크립팅 및 원격 관리와 같은 다양한 애플리케이션에서 유용하게 사용될 수 있습니다. 이러한 인터페이스가 제공하는 기능은 개발자와 고급 사용자 모두에게 높은 관심을 받고 있습니다.
Rust는 명령줄 인터페이스(CLI)를 구축하기 위한 언어 선택으로 점점 더 많은 관심을 받고 있습니다. 이는 메모리 할당에 대한 세분화된 제어 및 데이터 손상 방지와 같은 강력한 기능을 갖추고 있기 때문이며, 이 두 가지 기능은 보다 강력한 CLI 개발로 이어집니다. 또한 CLI 생성을 위해 특별히 설계된 라이브러리 및 프레임워크로 구성된 Rust의 활발한 에코시스템은 이 영역에서의 다재다능함을 강조합니다.
Rust로 CLI 앱 빌드 시작하기
최신 CLI 도구를 빌드하는 데 필요한 기능을 제공하는 Clap, StructOpt 및 Termion 크레이트와 같은 다양한 타사 패키지를 통해 Rust에서 CLI(명령줄 인터페이스) 애플리케이션을 쉽게 개발할 수 있습니다.
Rust 프로그래밍 언어는 표준 라이브러리 내에 환경 상자를 통합하여 개발자가 다양한 기술과 데이터 구조를 제공함으로써 크로스 플랫폼 방식으로 환경 변수 및 명령줄 매개 변수에 대한 작업을 수행할 수 있도록 합니다.
표준 라이브러리의 ‘std::env’를 활용하면 환경 변수, 명령줄 입력, 현재 작업 디렉토리 등 다양한 요소에 따라 Rust 프로그램과 주변 환경 간의 상호 작용이 가능하여 프로그램 동작을 수정할 수 있습니다.
cargo new crypto_cli
이 과정에서는 Rust 프로그래밍 언어로 HTTP 요청을 실행하기 위해 설계된 도구인 Reqwest 크레이트를 사용하여 코인마켓캡 API를 활용하는 명령줄 인터페이스(CLI) 애플리케이션을 만드는 방법을 배웁니다.
Cargo.toml 파일을 열고 Request 및 Tokio에 필요한 종속성을 추가했는지 확인하시기 바랍니다.
[dependencies]
tokio = { version = "1.15", features = ["full"] }
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Tokio는 비동기 프로그래밍을 위해 설계된 라이브러리로, Reqwest와 함께 사용할 수 있습니다. 비동기적으로 작업을 처리하는 효율적인 메커니즘을 제공하여 애플리케이션의 다양한 구성 요소 간의 통신을 용이하게 합니다. 또한 Serde와 Serde\_JSON은 JSON 형식의 데이터를 직렬화 및 역직렬화하는 데 사용됩니다. 이러한 상자는 프로그램의 여러 부분 간의 원활한 통신을 보장하는 데 중요한 역할을 합니다.
Rust 프로젝트의 “src” 디렉터리에 “api.rs”라는 파일과 API 호출 및 명령줄 인터페이스 사용 기능을 구현할 “cli.rs”라는 파일을 만드는 방법에 대한 자세한 지침은 제공된 설명서를 참조하시기 바랍니다.
touch src/api.rs src/cli.rs
Reqwest로 코인마켓캡의 API 요청하기
코인마켓캡의 API 를 사용하면 암호화폐 데이터에 액세스하고 애플리케이션에 통합할 수 있습니다. 이 API는 상장, 시세, 거래소 정보, 변환 도구, 과거 데이터 및 메타데이터에 대한 엔드포인트를 제공합니다.
로그인 후 코인마켓캡에서 계정을 만들고 플랫폼의 개발자 페이지를 방문하여 API 키를 받을 수 있습니다. 자세한 지침과 제한 사항은 첨부된 문서에서 확인할 수 있습니다.
“/v2/cryptocurrency/quotes/latest” 엔드포인트로 향하는 API 요청을 통해 하나 이상의 암호화폐에 대한 가장 최근 시세를 가져오려면 API에서 검색하고자 하는 정보의 구조를 개략적으로 설명하고 Serde의 파생 특성으로 특성을 표시해야 합니다.
지정된 위치에서 애플리케이션 프로그래밍 인터페이스(API)를 요청하고, 이후 serde\_json 라이브러리를 활용하여 JSON 데이터를 구조로 변환하여 Rust의 데이터 유형을 보다 편리하게 조작할 수 있습니다.
앞서 언급한 선언에는 지정된 디지털 자산의 식별자, 명명법, 기호 및 가격 정보를 추출하는 데 필요한 매개 변수가 포함됩니다.
#[derive(Debug, Deserialize, Serialize)]
struct ApiResponse {
data: Data,
}
#[derive(Debug, Deserialize, Serialize)]
struct Data {
// Add fields that you need from the data object
#[serde(rename = "1")]
crypto_1: Cryptocurrency,
#[serde(rename = "2")]
crypto_2: Cryptocurrency,
#[serde(rename = "3")]
crypto_3: Cryptocurrency,
#[serde(rename = "4")]
crypto_4: Cryptocurrency,
}
#[derive(Debug, Deserialize, Serialize)]
struct Cryptocurrency {
id: u32,
name: String,
symbol: String,
// Add other fields as needed
quote: Quote,
}
#[derive(Debug, Deserialize, Serialize)]
struct Quote {
USD: QuoteDetails,
}
#[derive(Debug, Deserialize, Serialize)]
struct QuoteDetails {
price: f64,
volume_24h: f64,
// Add other fields as needed
}
API를 사용하면 애플리케이션의 요구 사항을 초과하는 결과를 얻을 수 있지만, 앞서 설명한 것처럼 Serde 크레이트를 활용하면 필요한 특정 정보만 추출할 수 있습니다.
새 클라이언트를 인스턴스화하고 GET 요청에 필요한 파라미터를 지정하여 Reqwest를 활용하면 원하는 엔드포인트를 얻을 수 있습니다.
use reqwest::Client;
use reqwest::Error;
pub async fn crypto() -> Result<(), Error> {
let client = Client::new();
let url = "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest";
let params = [
("id", "1,2,3,4"),
("convert", "USD"), // Convert market values to USD
];
let response = client.get(url)
.header("X-CMC_PRO_API_KEY", "YOUR API KEY HERE")
.query(¶ms)
.send().await?;
;
let result: ApiResponse = serde_json::from_str(&*response.text().await?;).unwrap();
println!("{:#?}", result);
Ok(())
}
암호화 함수는 토큰이 지원하는 비동기 연산으로, `Client::new` 메서드를 사용하여 클라이언트 인스턴스를 초기화한 후 클라이언트의 `client.get` 메서드를 통해 엔드포인트에서 데이터를 검색합니다.
API 키를 나타내는 매개변수가 있는 RequestBuilder 클래스의 인스턴스에서 header() 메서드를 호출한 후 매개변수에 대해 작동하는 query() 함수를 실행한 다음 send() 함수를 실행하여 요청을 디스패치합니다.
암호화 함수는 JavaScript 객체 표기법(JSON) 문자열에서 작동하는 serde\_json 라이브러리의 “from\_str” 메커니즘을 활용하여 직렬화된 JSON 응답을 해독합니다.
암호화 함수는 직렬화 프로세스의 결과를 콘솔에 인쇄하여 종료합니다.
Rust에서 CLI 인수 검색
프로젝트 내에서 cargo 실행 명령을 실행할 때 사용자가 매개변수로 “crypto”를 입력하면 api.rs 파일에서 암호화 기능을 가져와 그에 따라 호출됩니다.
명령줄을 통해 전달된 입력을 추출하기 위해 다음과 같은 프로세스를 통해 `std::env` 함수를 사용할 수 있습니다:
use std::env;
use crate::api::crypto;
pub async fn cli() {
let args: Vec<String> = env::args().collect();
if args.len() > 1 && args[1] == "crypto" {
crypto().await.unwrap();
} else {
println!("Invalid command. Usage: cargo run crypto");
}
}
`cli` 함수는 `env::args().collect()` 함수를 사용하여 명령줄을 통해 전달된 모든 인수를 검색합니다. 그런 다음 조건부 검사를 수행하여 추가 인수인 “crypto”가 있는지 여부를 확인합니다. 조건이 `true`로 평가되면 `cli` 함수는 `crypto` 함수를 호출합니다. 반대로 평가 결과가 `false`인 경우 `cli` 함수는 콘솔에 메시지를 표시합니다.
궁극적으로 Rust의 `main` 함수에는 비동기 기능이 필요하기 때문에 `#[tokio::main]` 속성을 통합하여 기본 함수 내에서 CLI 함수를 실행할 수 있습니다.
mod api;
mod cli;
use crate::cli::cli;
#[tokio::main]
async fn main() {
cli().await;
}
메인 함수의 주요 목적은 Future의 결과를 얻을 때까지 작업을 일시적으로 중단하는 await 함수를 활용하여 명령줄 인터페이스(CLI)를 시작하는 것입니다.
“cargo run crypto” 명령을 실행하면 다음과 같은 결과가 나옵니다:
Rust로 정교한 웹 앱 구축 가능
적응형 프로그래밍 언어인 Rust는 다양한 영역에서 활용될 수 있는 수많은 가능성을 제시합니다. 웹 애플리케이션을 구축하기 위해 Actix, Rocket, Warp와 같은 타사 웹 프레임워크와 함께 사용할 수 있습니다. 이러한 프레임워크는 고급 웹 애플리케이션을 개발하는 데 필요한 대부분의 필수 기능을 제공합니다.