Preview version, will not guarantee the stability of the API! Do NOT use in production environment!
A library-first, lightweight, high-performance, cloud-native supported API gateway🪐
SpaceGate("Spacegates are Stargates suspended in space, or in planetary orbit") From "Stargate".
- Tiny: based on rust, the executable file only takes 6MB.
- Cloud Native: Implemented the Kubernetes Gateway API specification.
- Easy to extent: Build your own plugin with rust in just two function.
- Easy to extent: Build your own plugin with rust in just two function.
- High performance
- Low resource usage
kubectl apply -f https://github.com/ideal-world/spacegate/releases/download/0.2.0-alpha.2/spacegate-0.2.0-alpha.2.yaml
Build and install on your own linux machine.
sh resource/install/install.sh
This official manage tool will provide you a web interface to edit gateway's config.
sh resource/install/install-admin.sh
Visit localhost:9991 if you installed spacegate-admin manage tool.
firefox localhost:9991
Or visit config folder
ls /etc/spacegate
After you edited config, use systemctl to reload config.
sudo systemctl reload spacegate
Check the plugin folder:
ls /lib/spacegate/plugins
Just and put the .so
file under the plugin folder and configure it.
You can use spacegate-kernel
or spacegate-shell
. The The former one is relatively low-level, while the latter integrates plugins and configuration systems.
spacegate-shell = { git="https://github.com/ideal-world/spacegate" }
Start up by a config change listener
async fn main() {
let listener = todo!("create a listener!");
spacegate_shell::startup(listener).await;
}
or just using build-in listeners
// file config
spacegate_shell::startup_file("/etc/spacegate").await;
// k8s resource
spacegate_shell::startup_k8s(Some("spacegate-namespace")).await;
// fetch from redis
spacegate_shell::startup_redis("redis://my-redis").await;
spacegate-kernel = { git="https://github.com/ideal-world/spacegate" }
Create a listener and a gateway service
let cancel = CancellationToken::default();
// create a gateway service
let gateway = gateway::Gateway::builder("test_gateway")
.http_routers([(
"test_gateway".to_string(),
HttpRoute::builder()
.rule(
HttpRouteRule::builder()
.match_item(HttpPathMatchRewrite::prefix("/baidu"))
.backend(HttpBackend::builder().schema("https").host("www.baidu.com").port(443).build())
.build(),
)
.build(),
)])
.build();
let addr = SocketAddr::from_str("[::]:9002")?;
// create a listener
let listener = SgListen::new(
addr,
gateway.as_service(),
cancel.child_token(),
);
// start listen
listener.listen().await?;
All you need to do is to implements a Plugin
trait
use spacegate_plugin::{SgResponse, SgRequest, Inner, BoxError, PluginConfig, Plugin};
pub struct ServerHeaderPlugin {
header_value: String,
}
impl Plugin for ServerHeaderPlugin {
// an unique code for this plugin
const CODE: &'static str = "server-header";
// this will be called when request passthrough this plugin
async fn call(&self, req: SgRequest, inner: Inner) -> Result<SgResponse, BoxError> {
// pre-request process
// call inner to pass this request into inner layers
let mut resp = inner.call(req).await;
// post-request process
resp.headers_mut().insert("server", self.header_value.parse()?);
// return the result
Ok(resp)
}
// create a plugin instance from config
fn create(plugin_config: PluginConfig) -> Result<Self, BoxError> {
let Some(header_value) = plugin_config.spec.get("header_value") else {
return Err("missing header_value".into())
};
Ok(Self {
header_value: header_value.as_str().unwrap_or("spacegate").to_string(),
})
}
}
In your application program.
// register the plugin into global plugin repository
spacegate_plugin::PluginRepository::global().register::<ServerHeaderPlugin>()
Use the macro dynamic_lib
use spacegate_plugin::dynamic_lib;
dynamic_lib! { ServerHeaderPlugin }
and set the crate-type to dylib
[lib]
crate-type = ["dylib"]
After you got the lib file, load it in application program.
For example:
spacegate_plugin::PluginRepository::global().register_dylib("/lib/spacegate/plugins/mylib.so")
There are a lot of API gateway products out there, but they are mostly in the form of standalone services. The customization ability is relatively poor, and the cost of using and deploying is relatively high.
This project is based on the Rust
language and uses hyper
as the base network library. The goal is to: provide a library-first, lightweight, high-performance, cloud-native supported API gateway .
Release binary naming method: {crate}-{arch}{OS}{abi}-{version} download here
OS | Arch | abi | Remark |
---|---|---|---|
linux | x86_64,aarch64 | gnu,musl | If you need static linking please use musl |