Module tencent_scf::builtin::api [−][src]
This is supported on crate feature
builtin-api-gateway
only.Module for auto serialization/deserialization of Web API Gateway Trigger.
Overview
This modules implements auto serialization/deserialization of Web API Gateway Trigger events and responses as described in API Gateway Trigger Overview.
http::request::Request
, http::response::Response
and http::response::Builder
are
re-exported and user can directly use these types when constructing a serverless compute
function.
Note
There are some design decisions and limitation users may want to pay attention to:
- Since the query string is already parsed by the upstream cloud, we found it
counter-productive to re-encode it and put it back into the uri of the request. So we leave the
path as-is as the uri of the request and use the
extension
of the request to hold the parsed query string. User can acquire theString
-keyed query string as follows:use tencent_scf::builtin::api::ext; // Assume `req` is the incoming request let query_string = &req.extensions().get::<ext::QueryString>().unwrap().0;
- It is allowed to set path parameters, header parameters and query string parameters in the
API dashboard. We wrap these parameters in
ext::PathParameters
,ext::HeaderParameters
, andext::QueryStringParameters
and put them in the extension of the request as well. User can retrieve them likeext::QueryString
above. - The request context is wrapped in
ext::RequestContext
and can be retrieved just like above. - Multi-valued header is not supported in request due to a limitation in the format used by the upstream cloud protocol.
- Currently we only support
Request<T>/Response<T>
whereT
isString
orVec<u8>
. - For
Request<String>/Response<String>
, we assume the body is a utf-8 string and we don't do any processing. ForRequest<Vec<u8>>/Response<Vec<u8>>
however, we assume user wants a binary format, so we will assume that the incoming request is base64 encoded (as required by the cloud), and the runtime will try to decode the incoming event. We will also base64 encode the response before sending it out as well (as required by the cloud).
Example
Here is an example of a very primitive reverse proxy:
use std::{io::Read, str::FromStr}; use tencent_scf::{ builtin::api::{ ext, http::{ header::{HeaderName, HeaderValue}, Method, }, Request, Response, ResponseBuilder, }, make_scf, start, Context, }; extern crate ureq; const FORWARD_TARGET: &str = "http://example.com"; let scf = make_scf( |req: Request<Vec<u8>>, _context: Context| -> Result<Response<Vec<u8>>, ureq::Error> { // Check method if *req.method() == Method::GET { let forward_req = ureq::get(&format!("{}{}", FORWARD_TARGET, req.uri())); // Retrieve query string let query_string = &req.extensions().get::<ext::QueryString>().unwrap().0; let forward_req = query_string .iter() .fold(forward_req, |req, (key, value)| req.query(key, value)); // Set headers let forward_req = req .headers() .iter() .fold(forward_req, |req, (header, value)| { req.set(header.as_str(), value.to_str().unwrap()) }); // Send request let resp = forward_req.call()?; // Build response let mut forward_resp = ResponseBuilder::new().status(resp.status()); let headers = forward_resp.headers_mut().unwrap(); // Set headers for header in resp.headers_names() { for value in resp.all(&header) { headers.append( HeaderName::from_str(&header).unwrap(), HeaderValue::from_str(value).unwrap(), ); } } // Read response let mut reader = resp.into_reader(); let mut bytes: Vec<u8> = Vec::new(); reader.read_to_end(&mut bytes)?; // Assemble response Ok(forward_resp.body(bytes).unwrap()) } else { Ok(ResponseBuilder::new() .status(501) .body("Only GET method is supported".to_string().into_bytes()) .unwrap()) } }, ); start(scf);
Re-exports
pub use http; |
pub use http::request::Request; |
pub use http::response::Builder as ResponseBuilder; |
pub use http::response::Response; |
Modules
ext | Module that contains extensions in the |