Actix-Web - III

Veli Uysal
Turkiye Rust Community
4 min readAug 9, 2023

--

Daha önceki yazılarımda Actix kütüphanesiyle nasıl API geliştirilebilir için giriş yapmıştık ve URI için kullanılabilecek yapılardan bahsetmiştim. Şimdi ise bu yazıyla birlikte geliştireceğimiz API için kullandığımız URI’ler için nasıl HTTP metotları düzeyinde işlemler yapabileceğimizden bahsedeceğim. Hazırsanız haydi başlayalım ve Rusty’leşelim.

HTTP Metotları

Hypertext Transfer Protocol (HTTP), web tarayıcılarıyla web sunucuları arasında iletişim kurmak için kullanılan bir iletişim protokolüdür. HTTP, çeşitli HTTP metotları aracılığıyla farklı türde istekler göndermenizi ve sunucudan cevap almanızı sağlar. İşte yaygın olarak kullanılan HTTP metotları:

  1. GET: Belirtilen URL’den veri almak için kullanılır. Genellikle sunucudan veri çekmek veya bir web sayfasını görüntülemek için kullanılır.
  2. POST: Sunucuya veri göndermek için kullanılır. Örneğin, bir formun içeriğini sunucuya göndermek veya veritabanına yeni veri eklemek için kullanılabilir.
  3. PUT: Belirli bir URL’deki veriyi güncellemek veya oluşturmak için kullanılır. Varolan bir kaynağı değiştirmek veya yeni bir kaynak oluşturmak için kullanılabilir.
  4. PATCH: Belirli bir kaynağın kısmi güncellemesini yapmak için kullanılır. Yani, kaynağın sadece bazı alanlarını değiştirmek istediğinizde kullanılabilir.
  5. DELETE: Belirtilen URL’deki bir kaynağı silmek için kullanılır. Sunucudan bir kaynağı kaldırmak için kullanılır.
  6. HEAD: GET metoduyla aynı işlevi görür, ancak sadece başlık (header) bilgilerini döner. İçerik (body) verisi döndürmez.
  7. OPTIONS: Belirtilen URL’ye yapılabilecek HTTP istek türlerini sorgulamak için kullanılır. Sunucunun desteklediği metotları ve diğer özellikleri almak için kullanılır.
  8. CONNECT: Sunucuyla güvenli bir bağlantı kurmak için kullanılır, genellikle SSL/TLS gibi durumlar için kullanılır.
  9. TRACE: Sunucuya, isteğin aynen nasıl geldiğini göndermek için kullanılır. Genellikle hata ayıklama veya izleme amacıyla kullanılır.

Bu HTTP metotları, web tarayıcılarının ve sunucularının birbirleriyle etkileşim kurmasını sağlayan temel yapı taşlarıdır. İstemciler (örneğin, web tarayıcıları) bu metotları kullanarak sunuculara çeşitli isteklerde bulunur ve sunucular da bu isteklere uygun yanıtlar verir.

Extractors

Actix ile bir API geliştirirken dışarıya açacağımız bazı URI’ler sadece string ifadeler içermeyebilir. Bazen içerisinde parametreleri barındırması gerekebilir bu durumda da Actix bize Extractor ismini verdiği yapılar yardımcı olur. Haydi bu yapılar nelerdir birlikte bakalım.

  • Path Extractor: Bu extractor ile bizim URI ifademiz içerisinde bulununan ve örneğin bizim ID ile dallanmasını istediğimiz endpointlerde kullanılır. Daha önce bir API geliştirmesi yapanlar bunun URI Path üzerinde işlem yapmamıza olanak sağlayan yapılar olduğunu göreceklerdir.

Kullanımı ise web::Path<> şeklindedir. < ile > arasına bizim URI içerisinde bulunan değerlerin beklenen tipleri sırasıyla yazılarak çeşitlendirebiliriz. Gelin bu dediğimi kod olarak görelim.

use actix_web::{get, web, App, HttpServer, Result};

/// extract path info from "/users/{user_id}/{friend}" url
/// {user_id} - deserializes to a u32
/// {friend} - deserializes to a String
#[get("/users/{user_id}/{friend}")] // <- define path parameters
async fn index(path: web::Path<(u32, String)>) -> Result<String> {
let (user_id, friend) = path.into_inner();
Ok(format!("Welcome {}, user_id {}!", friend, user_id))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(index))
.bind(("127.0.0.1", 8080))?
.run()
.await
}

Yukarıdaki örnekte görüldüğü üzere bizim GET HTTP Metoduyla kullandığımız URI içerisinde {user_id} ve {friend} ifadeleri görülmektedir. Bu ifadelerin tipleri olarakta web::Path<(u32, String)> şeklinde bir ifadeyle belirtilmektedir. Bu URI değerine istek atmak istediğimizde bizim user_id ve friend ifadeleri yerine değerler vermemiz gerekmektedir.

Yukarıdaki örneğimizde kullandığımız ifadelerin daha derli toplu olarak durmasını istediğimizde bunları bir struct içerisinde tanımlayarak kullanabiliriz. Bu kullanım örneği de aşağıdaki gibidir.

use actix_web::{get, web, Result};
use serde::Deserialize;

#[derive(Deserialize)]
struct Info {
user_id: u32,
friend: String,
}

/// extract path info using serde
#[get("/users/{user_id}/{friend}")] // <- define path parameters
async fn index(info: web::Path<Info>) -> Result<String> {
Ok(format!(
"Welcome {}, user_id {}!",
info.friend, info.user_id
))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer};

HttpServer::new(|| App::new().service(index))
.bind(("127.0.0.1", 8080))?
.run()
.await
}

Burada dikkat edilmesi gereken isim,tip ve sıralamanın aynı olması gerekmektedir.

  • Query Extractor: Bu yapımızda ise bizim URI içerisinde Query Parametresi(“?user_id=&friend=”) ile veri gönderdiğimiz durumlarda kullanıyoruz. Bu ifadeleri de metot içerisinde kullanmak için web::Query<> şeklinde bir ifadeyle parametre olarak geçilmesi gerekmektedir. Kullanım örneği ise aşağıdadır.
use actix_web::{get, web, App, HttpServer};
use serde::Deserialize;

#[derive(Deserialize)]
struct Info {
username: String,
}

// this handler gets called if the query deserializes into `Info` successfully
// otherwise a 400 Bad Request error response is returned
#[get("/")]
async fn index(info: web::Query<Info>) -> String {
format!("Welcome {}!", info.username)
}
  • JSON Extractor: Bizim URI ile Request Body gönderdiğimiz durumlarda kullandığımız bir extractor. Body parametresinde JSON olarak gönderdiğimiz verileri daha kolay yönetmemizi sağlamaktadır. Kullandığımız URI metodunda kullanmak için web::Json<> şeklinde bir ifadeyle parametre geçirmemiz gerekmektedir. Kullanım örneği aşağıdadır.
use actix_web::{post, web, App, HttpServer, Result};
use serde::Deserialize;

#[derive(Deserialize)]
struct Info {
username: String,
}

/// deserialize `Info` from request's body
#[post("/submit")]
async fn submit(info: web::Json<Info>) -> Result<String> {
Ok(format!("Welcome {}!", info.username))
}
  • URL-Encoded Forms Extractor: Bizim URI içerisinde body parametresinin “x-www-form-urlencoded” ile gönderilmesi gereken durumlarda kullanılan bir extractor yapısıdır. Metot içerisinde web::Form<> şeklinde bir ifadeyle parametre geçirmemiz gerekmektedir. Kullanım örneği aşağıdadır.
use actix_web::{post, web, App, HttpServer, Result};
use serde::Deserialize;

#[derive(Deserialize)]
struct FormData {
username: String,
}

/// extract form data using serde
/// this handler gets called only if the content type is *x-www-form-urlencoded*
/// and the content of the request could be deserialized to a `FormData` struct
#[post("/")]
async fn index(form: web::Form<FormData>) -> Result<String> {
Ok(format!("Welcome {}!", form.username))
}
  • Data — Application state bilgilerine erişim için kullanılır.
  • HttpRequest - Request objesine erişim için kullanılır.
  • String - Request objecsini String veri tipine dönüştürüp kullanmak için.
  • Bytes - Request objesini Bytes veri tipine dönüşütürüp kullanabilmek için.
  • Payload - Kendi extractor’larımızı yazmamıza olanak sağlayan düşük seviyeli bir extractor’dır.

Daha fazla bilgiye ulaşmak için bu likten faydalanabilirsiniz.

Sosyal medya hesaplarım: Twitter | Linkedin | Github | Youtube

--

--