ã¯ããã«
Protocol Buffersã¨Rustã®å®è·µçãªå¦ç¿ãç®çã¨ãã¦å³æ¸ç®¡çã·ã¹ãã ãéçºãã¾ããã ã·ã¹ãã ã®æ§ç¯ã«ããã£ã¦ã¯Bufã«ããã¹ãã¼ã管çã¨ã³ã¼ãçæãæ¡ç¨ãããã¨ã§éçºç°å¢ãå®ç¾ãã¦ãã¾ããä»åã®å®è£ ãéãã¦Rustã«ãããgRPCãµã¼ãã¹ã®æ§ç¯ææ³ã«ã¤ãã¦ç解ãæ·±ãããã¨ãã§ãã¾ããã
ããã³ãã¨ã³ãéçºã«ã¤ãã¦ã¯ä»å¾ã®èª²é¡ã¨ãã¦æ¤è¨ãã¦ãã¾ãã Remixãæ°ã«ãªã£ã¦ããã®ã§å®è£ ãããã¨æã£ã¦ã¾ããæ¬è¨äºã§ã¯ããã¯ã¨ã³ãå®è£ ã«ç¦ç¹ãå½ã¦ã¦è§£èª¬ãã¾ãã ç¹ã«Rustã®ã¨ã³ã·ã¹ãã ã«ãããtonicãSQLxã¨ãã£ãã©ã¤ãã©ãªã®æ´»ç¨æ¹æ³ã«çç®ãã¾ãããããã®å®è£ ãéãã¦å¾ãããç¥è¦ã¯ä»ã®Rustããã¸ã§ã¯ãã«ãå¿ç¨å¯è½ãªå 容ã¨ãªã£ã¦ãã¾ãã
å¦ç¿ç®çã§å®è£ ããã³ã¼ããªã®ã§ä½ãã«æ´»ç¨ãã¦ããã ããã°å¹¸ãã§ãã
ããã¸ã§ã¯ãã®ã»ããã¢ãã
ã¾ãã以ä¸ã®ãããªãã£ã¬ã¯ããªæ§é ãä½æãã¾ãï¼
library-system/ âââ buf/ â âââ buf.yaml â âââ buf.gen.yaml â âââ library/ â âââ v1/ â âââ library.proto âââ library-server/ âââ library-client/
Bufã®è¨å®
buf.yaml
:
version: v1 name: buf.build/yourusername/library-system breaking: use: - FILE lint: use: - DEFAULT
buf.gen.yaml
:
version: v1 plugins: - plugin: buf.build/protocolbuffers/rust out: ../library-server/src opt: - bytes=bytes - plugin: buf.build/community/neoeinstein-tonic-rust out: ../library-server/src opt: - no_client=false - no_server=false
APIã®è¨è¨
Protocol Buffersã使ç¨ãã¦APIãå®ç¾©ãã¾ãï¼
syntax = "proto3"; package library.v1; import "google/protobuf/timestamp.proto"; service LibraryService { rpc CreateUser(CreateUserRequest) returns (CreateUserResponse); rpc GetUser(GetUserRequest) returns (GetUserResponse); rpc SearchBooks(SearchBooksRequest) returns (SearchBooksResponse); rpc CreateLoan(CreateLoanRequest) returns (CreateLoanResponse); rpc ReturnBook(ReturnBookRequest) returns (ReturnBookResponse); }
å³æ¸ç®¡çã·ã¹ãã ã®å®è£ 詳細
ã¢ã¼ããã¯ãã£ã¨æè¡é¸å®
ã·ã¹ãã ã®åºç¤ã«ã¯éåæå¦çã«ããé«ããã©ã¼ãã³ã¹ãªå®è£ ãæ¡ç¨ãã¾ããã Rustã®éåæã©ã³ã¿ã¤ã ã§ããtokioãæ´»ç¨ãããã¨ã§ãªã½ã¼ã¹ã®å¹ççãªå©ç¨ãå®ç¾ãã¾ãããµã¼ãã¼ã®èµ·åå¦çã¯ä»¥ä¸ã®ã³ã¼ãã§ç¤ºãããã«éåæå¦çãåºæ¬ã¨ããè¨è¨ã§ãã
#[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let service = LibraryServiceImpl::new(&database_url).await?; Server::builder() .add_service(LibraryServiceServer::new(service)) .serve(addr) .await?; Ok(()) }
ãµã¼ãã¼ãµã¤ãã®ä¸»è¦å®è£
Protocol Buffersã«ãããµã¼ãã¹å®ç¾©ãå®è£
ã®èµ·ç¹ã¨ãªãã¾ãã ãµã¼ãã¼ã®ä¸æ ¸æ©è½ã¯LibraryServiceImpl
æ§é ä½ã«éç´ããã¾ããSQLxãç¨ãããã¼ã¿ãã¼ã¹æä½ã«ããåå®å
¨æ§ã®é«ãã³ã¼ããå®ç¾ãã¾ããã
貸åºå¦çã®ãã©ã³ã¶ã¯ã·ã§ã³å¶å¾¡ã¯ç¹ã«æ éãªå®è£ ãå¿ è¦ã¨ãã¾ããã 以ä¸ã®ã³ã¼ãã§ã¯æ¸ç±ã®è²¸åºç¶æ 確èªããæ´æ°ã¾ã§ãåä¸ãã©ã³ã¶ã¯ã·ã§ã³ã§å¦çãã¾ãã
async fn create_loan(&self, request: Request<CreateLoanRequest>) -> Result<Response<CreateLoanResponse>, Status> { let mut tx = self.pool.begin().await?; let book = sqlx::query_scalar::<_, bool>("SELECT available FROM books WHERE id = ?") .bind(&req.book_id) .fetch_optional(&mut *tx) .await?; if !book.available { return Err(Status::failed_precondition("Book is not available")); } // 貸åºå¦çã®å®è¡ tx.commit().await?; Ok(Response::new(loan_response)) }
ã¯ã©ã¤ã¢ã³ããµã¤ãã®å®è£
ã¦ã¼ã¶ã¼ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¯ç´æçãªæä½ãéè¦ãã¾ããã ã¯ã©ã¤ã¢ã³ãã®åæåå¦çã¯ä»¥ä¸ã®ããã«ç°¡æ½ãªå®è£ ã¨ãã¦ãã¾ãã
async fn main() -> Result<(), Box<dyn std::error::Error>> { let channel = Channel::from_static("http://[::1]:50051").connect().await?; let client = LibraryServiceClient::new(channel); }
ã¨ã©ã¼å¦çã¯å©ç¨è ã®è¦ç¹ãéè¦ããå®è£ ã¨ãã¾ããã ãµã¼ãã¼ããã®ã¨ã©ã¼ã¬ã¹ãã³ã¹ãé©åã«ãã³ããªã³ã°ãããã¨ã§ã¦ã¼ã¶ã¼ã¸ã®æ確ãªãã£ã¼ãããã¯ãå®ç¾ãã¾ãã
ãã¼ã¿ãã¼ã¹è¨è¨
ãã¼ã¿ã¢ãã«ã¯æ¥åè¦ä»¶ãæ£ç¢ºã«åæ ããè¨è¨ã¨ãã¾ããã ã¦ã¼ã¶ã¼æ å ±ã¨æ¸ç±æ å ±ã管çããåºæ¬ãã¼ãã«ã«å ãã¦è²¸åºå±¥æ´ãè¨é²ãããã¼ãã«ãå®è£ ãã¾ãã
CREATE TABLE loans ( id TEXT PRIMARY KEY, book_id TEXT NOT NULL REFERENCES books(id), user_id TEXT NOT NULL REFERENCES users(id), loan_date TIMESTAMP NOT NULL, due_date TIMESTAMP NOT NULL, return_date TIMESTAMP );
ã¹ãã¼ãè¨è¨ã¯å°æ¥ã®æ¡å¼µæ§ãèæ ®ãã¾ããã è¿å´æ¥æã貸åºç¶æ ã管çããã«ã©ã ã追å ãããã¨ã§æ©è½æ¡å¼µã¸ã®å¯¾å¿ãå¯è½ã¨ãã¦ãã¾ãã
ãã®å®è£ ãéãã¦å¦ãã æãéè¦ãªç¹ã¯åå®å ¨æ§ã¨ãã©ã³ã¶ã¯ã·ã§ã³ç®¡çã®éè¦æ§ã§ããRustã¨SQLxã®çµã¿åããã«ããå ç¢ãªã·ã¹ãã ãå®ç¾ã§ãã¾ããã
主è¦ãªæ©è½
ã¦ã¼ã¶ã¼ç®¡ç
- ã¦ã¼ã¶ã¼ã®ä½æ
- ã¦ã¼ã¶ã¼æ å ±ã®åå¾
æ¸ç±ç®¡ç
- æ¸ç±ã®æ¤ç´¢
- å¨åº«ç¶æ ã®ç®¡ç
貸åºç®¡ç
- æ¸ç±ã®è²¸åº
- è¿å´å¦ç
- 貸åºç¶æ ã®è¿½è·¡
åèãªã½ã¼ã¹
- Buf Documentation
- Tonic Documentation
- SQLx Documentation
- Protocol Buffers Documentation
- Generated SDKs for Rust now available on the Buf Schema Registry
ã¾ã¨ã
ä»åã¯å³æ¸ç®¡çã·ã¹ãã ãé¡æã«Rustã¨Protocol Buffersãçµã¿åãããå®è£ ãæ¤è¨¼ãã¾ããã tonicã¨SQLxãæ´»ç¨ããããã¯ã¨ã³ãéçºãéãã¦ä¸¡è ã®è¦ªåæ§ã®é«ããå®æã§ãã¾ãããRustã®åã·ã¹ãã ã¨ææ権ã®æ¦å¿µãProtocol Buffersã®åå®ç¾©ã¨èªç¶ã«èª¿åããç¹ãç¹ã«å°è±¡çã§ããã
ã¨ã©ã¼å¦çã¨éåæããã°ã©ãã³ã°ã®å®è£ ãã¿ã¼ã³ã«ã¤ãã¦ãææ義ãªç¥è¦ãå¾ããã¾ããã Rustã®Resultåã¨tonicã®ã¹ãã¼ã¿ã¹ã³ã¼ãã®çµã¿åããã¯æå¿«ãªã¨ã©ã¼ãã³ããªã³ã°ãå®ç¾ãã¾ããã¾ãtokioãåºç¤ã¨ããéåæå¦çã¯SQLxã®ãã©ã³ã¶ã¯ã·ã§ã³ç®¡çã¨çµã¿åããããã¨ã§å ç¢ãªå®è£ ãå¯è½ã«ãã¾ãã
ä»å¾ã¯æ¬å®è£ ããã¼ã¹ã«ãããªãæ¤è¨¼ãé²ãããã¨èãã¦ãã¾ãã äºç´ã·ã¹ãã ãã¦ã¼ã¶ã¼èªè¨¼ã®è¿½å ãéãã¦ã¹ã±ã¼ã©ãã«ãªè¨è¨ã®å¯è½æ§ãæ¢ãã¾ããããã³ãã¨ã³ãéçºã§ã¯Remixã¨TypeScriptãæ¡ç¨ãããã¨ã§ã¨ã³ããã¼ã¨ã³ãã®åå®å ¨æ§ã«ã¤ãã¦ãæ¤è¨¼ãè¡ãäºå®ã§ããã¾ãDockerã³ã³ããåãCI/CDãã¤ãã©ã¤ã³ã®æ´åãéãã¦æ¬çªç°å¢ã§ã®éç¨æ§ã確èªãã¦ããã¾ãã
Rustã¨Protocol Buffersã主軸ã¨ããæ¬ããã¸ã§ã¯ãã¯å®ç¨çãªã·ã¹ãã éçºã®åºç¤ã¨ãã¦ååãªæå¿ããæããçµæã¨ãªãã¾ãããä»åå¾ãããç¥è¦ã¯ä»å¾ã®éçºããã¸ã§ã¯ãã«ã大ãã«æ´»ç¨ã§ãããã®ã¨ç¢ºä¿¡ãã¦ãã¾ãã
æå¾ã«
åæ¥ã®èªã æ°ãã«å»ã¿ãã æ¨æ¥ã®å½±ã ã¾ã ç§ãé¢ãã
ç®æ¨ã¨ããæ㯠é ãè¼ãã© æã®å±ãã¬ç©ºã« ãã æºãã¦ãã
æ¥ã ã¯å·ã®æµãã®ããã« å¤ããã¬å ´æã éãã«éããã
ããã©çã¯é²ã¿ å»ã¯ç¢ºãã« ç§ãè²ã¦ã
ææ¥ãã¾ã æ°ããæãæ¥ã ããã ãã 確ããªçå®