项目作者: webwire

项目描述 :
Webwire Command Line Interface
高级语言: Rust
项目地址: git://github.com/webwire/webwire-cli.git
创建时间: 2020-02-14T16:20:49Z
项目社区:https://github.com/webwire/webwire-cli

开源协议:Other

下载


Webwire command-line Interface

Crates.io
GitHub Workflow Status

Discord Chat

webwire logo

Webwire is a contract-first API system which features an
interface description language a network protocol and
code generator for both servers and clients.

This repository contains the the command-line interface used
to validate Webwire IDL files and generate code and documentation.

To learn more about webwire in general please visit the documentation
repository webwire/webwire-docs.

Example

The following example assumes a Rust server and a TypeScript client. Webwire
is by no means limited to those two but those languages show the potential of
webwire best.

Given the following IDL file:

  1. struct HelloRequest {
  2. name: String,
  3. }
  4. struct HelloResponse {
  5. message: String,
  6. }
  7. service Hello {
  8. hello: HelloRequest -> HelloResponse
  9. }

The server and client files can be generated using the code generator:

  1. $ webwire gen rust < api/chat.ww > server/src/api.rs
  2. $ webwire gen ts < api/chat.ww > client/src/api.ts

A Rust server implementation for the given code would look like this:

  1. use std::net::SocketAddr;
  2. use std::sync::{Arc};
  3. use async_trait::async_trait;
  4. use ::api::chat;
  5. use ::webwire::server::hyper::MakeHyperService;
  6. use ::webwire::server::session::{Auth, AuthError};
  7. use ::webwire::{Response, Router, Server, ConsumerError};
  8. struct ChatService {
  9. #[allow(dead_code)]
  10. session: Arc<Session>,
  11. server: Arc<Server<Session>>,
  12. }
  13. #[async_trait]
  14. impl chat::Server<Session> for ChatService {
  15. async fn send(&self, message: &chat::Message) -> Response<Result<(), chat::SendError>> {
  16. let client = chat::ClientConsumer(&*self.server);
  17. assert!(matches!(client.on_message(message).await, Err(ConsumerError::Broadcast)));
  18. Ok(Ok(()))
  19. }
  20. }
  21. #[derive(Default)]
  22. struct Session {}
  23. struct Sessions {}
  24. impl Sessions {
  25. pub fn new() -> Self {
  26. Self {}
  27. }
  28. }
  29. #[async_trait]
  30. impl webwire::SessionHandler<Session> for Sessions {
  31. async fn auth(&self, _auth: Option<Auth>) -> Result<Session, AuthError> {
  32. Ok(Session::default())
  33. }
  34. async fn connect(&self, _session: &Session) {}
  35. async fn disconnect(&self, _session: &Session) {}
  36. }
  37. #[tokio::main]
  38. async fn main() {
  39. // Create session handler
  40. let session_handler = Sessions::new();
  41. // Create service router
  42. let router = Arc::new(Router::<Session>::new());
  43. // Create webwire server
  44. let server = Arc::new(webwire::server::Server::new(
  45. session_handler,
  46. router.clone(),
  47. ));
  48. // Register services
  49. router.service(chat::ServerProvider({
  50. let server = server.clone();
  51. move |session| ChatService {
  52. session,
  53. server: server.clone(),
  54. }
  55. }));
  56. // Start hyper service
  57. let addr = SocketAddr::from(([0, 0, 0, 0], 2323));
  58. let make_service = MakeHyperService { server };
  59. let server = hyper::Server::bind(&addr).serve(make_service);
  60. if let Err(e) = server.await {
  61. eprintln!("server error: {}", e);
  62. }
  63. }

A TypeScript client using the generated code would look like that:

  1. import { Client } from 'webwire'
  2. import api from 'api' // this is the generated code
  3. let client = new Client('http://localhost:8000/', [
  4. api.chat.ClientProvider({
  5. async on_message(message) {
  6. console.log("Message received:", message)
  7. }
  8. })
  9. ])
  10. assert(await client.connect())
  11. let chat = api.chat.ServerConsumer(client)
  12. let response = await chat.message({ text: "Hello world!" })
  13. assert(response.Ok === null)

License

Licensed under either of

at your option.