Skip to content

Commit

Permalink
feat: api complete
Browse files Browse the repository at this point in the history
  • Loading branch information
jayy-lmao committed Jun 1, 2024
1 parent 51f5ea9 commit 7b4bb38
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 44 deletions.
81 changes: 54 additions & 27 deletions src/order_taking/place_order/api.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
// 3) The output is turned into a DTO which is turned into a HttpResponse
// ======================================================

import gleam/http/request
import gleam/http/response
import gleam/json
import gleam/list
import gleam/result
import order_taking/common/simple_types/price
import order_taking/place_order/dto/order_form_dto
import order_taking/place_order/dto/place_order_error_dto
import order_taking/place_order/dto/place_order_event_dto
import order_taking/place_order/implementation
Expand All @@ -35,12 +38,12 @@ pub fn check_product_exists(_product_code) {
pub fn check_address_exists(unvalidated_address) {
let checked_address = implementation.CheckedAddress(unvalidated_address)

checked_address
Ok(checked_address)
}

/// dummy implementation
pub fn get_product_price(_product_code) {
price.from_int(1)
result.unwrap(price.from_int(1), price.zero())
}

/// dummy implementation
Expand Down Expand Up @@ -94,28 +97,52 @@ pub fn workflow_result_to_http_reponse(result) -> response.Response(String) {
}
}
}
// let placeOrderApi : PlaceOrderApi =
// fun request ->
// // following the approach in "A Complete Serialization Pipeline" in chapter 11

// // start with a string
// let orderFormJson = request.Body
// let orderForm = deserializeJson<OrderFormDto>(orderFormJson)
// // convert to domain object
// let unvalidatedOrder = orderForm |> OrderFormDto.toUnvalidatedOrder

// // setup the dependencies. See "Injecting Dependencies" in chapter 9
// let workflow =
// Implementation.placeOrder
// checkProductExists // dependency
// checkAddressExists // dependency
// getProductPrice // dependency
// createOrderAcknowledgmentLetter // dependency
// sendOrderAcknowledgment // dependency

// // now we are in the pure domain
// let asyncResult = workflow unvalidatedOrder

// // now convert from the pure domain back to a HttpResponse
// asyncResult
// |> Async.map (workflowResultToHttpReponse)

pub fn place_order_api(
request: request.Request(String),
) -> response.Response(String) {
// following the approach in "A Complete Serialization Pipeline" in chapter 11

// start with a string
let order_form_json = request.body
let order_form =
json.decode(from: order_form_json, using: order_form_dto.decoder())

case order_form {
Ok(order_form) -> {
// convert to domain object
let unvalidated_order = order_form |> order_form_dto.to_unvalidated_order

// setup the dependencies. See "Injecting Dependencies" in chapter 9
let workflow =
implementation.place_order(
check_product_exists,
// dependency
check_address_exists,
// dependency
get_product_price,
// dependency
create_order_acknowledgment_letter,
// dependency
send_order_acknowledgment,
// dependency
)

// now we are in the pure domain
let result = workflow(unvalidated_order)

// now convert from the pure domain back to a HttpResponse
result
|> workflow_result_to_http_reponse
}
Error(_json_error) -> {
let response =
response.Response(
status: 403,
body: "JSON deserialisation error",
headers: [],
)
response
}
}
}
4 changes: 2 additions & 2 deletions src/order_taking/place_order/dto/address_dto.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub type AddressDto {
}

/// For deserialising
pub fn from_json(json_string: String) -> Result(AddressDto, json.DecodeError) {
pub fn decoder() {
let decoder =
dynamic.decode6(
AddressDto,
Expand All @@ -31,7 +31,7 @@ pub fn from_json(json_string: String) -> Result(AddressDto, json.DecodeError) {
dynamic.field("zip_code", of: dynamic.string),
)

json.decode(from: json_string, using: decoder)
decoder
}

/// For serialising
Expand Down
6 changes: 2 additions & 4 deletions src/order_taking/place_order/dto/customer_info_dto.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ pub type CustomerInfoDto {
}

/// For deserialising
pub fn from_json(
json_string: String,
) -> Result(CustomerInfoDto, json.DecodeError) {
pub fn decoder(json_string: String) {
let decoder =
dynamic.decode3(
CustomerInfoDto,
Expand All @@ -26,7 +24,7 @@ pub fn from_json(
dynamic.field("email_address", of: dynamic.string),
)

json.decode(from: json_string, using: decoder)
decoder
}

/// For serialising
Expand Down
30 changes: 23 additions & 7 deletions src/order_taking/place_order/dto/order_form_dto.gleam
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
import gleam/dynamic
import gleam/list
import order_taking/common/public_types
import order_taking/place_order/dto/address_dto.{type AddressDto}
import order_taking/place_order/dto/customer_info_dto.{type CustomerInfoDto}
import order_taking/place_order/dto/order_line_dto.{type OrderFormLineDto}
import order_taking/place_order/dto/address_dto
import order_taking/place_order/dto/customer_info_dto
import order_taking/place_order/dto/order_line_dto

pub type OrderFormDto {
OrderFormDto(
order_id: String,
customer_info: CustomerInfoDto,
shipping_address: AddressDto,
billing_address: AddressDto,
lines: List(OrderFormLineDto),
customer_info: customer_info_dto.CustomerInfoDto,
shipping_address: address_dto.AddressDto,
billing_address: address_dto.AddressDto,
lines: List(order_line_dto.OrderFormLineDto),
)
}

/// For deserialising
pub fn decoder() {
let decoder =
dynamic.decode5(
OrderFormDto,
dynamic.field("order_id", of: dynamic.string),
dynamic.field("customer_info", of: customer_info_dto.decoder()),
dynamic.field("shipping_address", of: address_dto.decoder()),
dynamic.field("billing_address", of: address_dto.decoder()),
dynamic.field("lines", of: dynamic.list(order_line_dto.decoder())),
)

decoder
}

/// Convert the OrderForm into a UnvalidatedOrder
/// This always succeeds because there is no validation.
pub fn to_unvalidated_order(dto: OrderFormDto) -> public_types.UnvalidatedOrder {
Expand Down
6 changes: 2 additions & 4 deletions src/order_taking/place_order/dto/order_line_dto.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ pub type OrderFormLineDto {
}

/// For deserialising
pub fn from_json(
json_string: String,
) -> Result(OrderFormLineDto, json.DecodeError) {
pub fn decoder() {
let decoder =
dynamic.decode3(
OrderFormLineDto,
Expand All @@ -23,7 +21,7 @@ pub fn from_json(
dynamic.field("quantity", of: dynamic.string),
)

json.decode(from: json_string, using: decoder)
decoder
}

/// For serialising
Expand Down

0 comments on commit 7b4bb38

Please sign in to comment.