Request and response types

The main struct is Unicorn, which contains the creature we will ride:

#[derive(Clone, Serialize)]
#[serde(rename_all = "PascalCase")]
struct Unicorn {
name: String,
color: String,
gender: String,
}

Every Unicorn has a name, color, and gender. We will store these values as items in a DynamoDB record. To simplify the creation of the instance in the code, we will add the following constructor:

impl Unicorn {
fn new(name: &str, color: &str, gender: &str) -> Self {
Unicorn {
name: name.to_owned(),
color: color.to_owned(),
gender: gender.to_owned(),
}
}
}

You may ask why we don't represent color and gender with enumerations. It's possible, but you have to be sure that the serialized values are exactly what you want.

The Location struct represents a point on a map that will be set by the UI of the application:

#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Location {
latitude: f64,
longitude: f64,
}

Now we can declare a Request struct that contains body and request_context fields, which we will use to get a username provided by Cognito. You may have noticed that the Location structs have different renaming rules than other structs. That's because the Request struct was parsed by API Gateway, but Location and RequestBody will be created by the frontend application, which uses other identifiers. Request represents the body as a String:

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct Request {
body: String,
request_context: RequestContext,
}

RequestContext is a map that is filled by the runtime, and we will parse it to a struct:

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct RequestContext {
authorizer: Authorizer,
}

We need an Authorizer field that only contains claims values:

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct Authorizer {
claims: HashMap<String, String>,
}

We used claims to get the cognito:username value in the handler.

#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
struct RequestBody {
pickup_location: Location,
}

Now we can declare a Response. It is also used by API Gateway and has to contain status_code and headers:

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Response {
body: String,
status_code: u16,
headers: HashMap<String, String>,
}

The body field is represented by a String type that we will deserialize separately to the ResponseBody struct:

#[derive(Serialize)]
#[serde(rename_all = "PascalCase")]
struct ResponseBody {
ride_id: String,
unicorn: Unicorn,
unicorn_name: String,
eta: String,
rider: String,
}

The preceding fields are necessary for frontend applications from the workshop.

Now we can add functions to generate the Unicorn instance and to add a record to a database.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.209.201