admin管理员组

文章数量:1390767

I have the following code that makes a HTTP API call and returns JSON which I have to decode:

import gleam/dynamic/decode
import gleam/hackney
import gleam/http/request
import gleam/io
import gleam/json
import gleam/result.{try}
import gleeunit/should

type Rating {
  Rating(rate: Float, count: Int)
}

fn rating_decoder() {
  use rate <- decode.field("rate", decode.float)
  use count <- decode.field("count", decode.int)
  decode.success(Rating(rate, count))
}

type Product {
  Product(
    id: Int,
    title: String,
    price: Float,
    description: String,
    category: String,
    image: String,
    rating: Rating,
  )
}

fn product_from_json(
  json_string: String,
) -> Result(List(Product), json.DecodeError) {
  let product = {
    use id <- decode.field("id", decode.int)
    use title <- decode.field("title", decode.string)
    use price <- decode.field("price", decode.float)
    use description <- decode.field("description", decode.string)
    use category <- decode.field("category", decode.string)
    use image <- decode.field("image", decode.string)
    use rating <- decode.field("rating", rating_decoder())
    decode.success(Product(
      id,
      title,
      price,
      description,
      category,
      image,
      rating,
    ))
  }
  json.parse(from: json_string, using: decode.list(product))
}

pub fn main() {
  // Prepare a HTTP request record
  let assert Ok(request) = request.to(";)

  // Send the HTTP request to the server
  use response <- try(
    request
    |> hackney.send,
  )

  // We get a response record back
  response.status
  |> should.equal(200)

 response
  |> response.get_header("content-type")
  |> should.equal(Ok("application/json; charset=utf-8"))


  //io.println(response.body)

  let json_string =
    "[{\"id\":1,\"title\":\"Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops\",\"price\":109.95,\"description\":\"Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday\",\"category\":\"men's clothing\",\"image\":\"._AC_SL1500_.jpg\",\"rating\":{\"rate\":3.9,\"count\":120}}]"

  case product_from_json(response.body) {
    Ok(products) -> echo products
    Error(_error) -> {
      io.println("Failed to parse JSON: ")
      []
    }
  }


  Ok(Nil)
}

Here is the CURL command:

curl -X GET ''

When I use sample JSON payload it works, but when I use the API response it fails. What am I doing wrong?

I have the following code that makes a HTTP API call and returns JSON which I have to decode:

import gleam/dynamic/decode
import gleam/hackney
import gleam/http/request
import gleam/io
import gleam/json
import gleam/result.{try}
import gleeunit/should

type Rating {
  Rating(rate: Float, count: Int)
}

fn rating_decoder() {
  use rate <- decode.field("rate", decode.float)
  use count <- decode.field("count", decode.int)
  decode.success(Rating(rate, count))
}

type Product {
  Product(
    id: Int,
    title: String,
    price: Float,
    description: String,
    category: String,
    image: String,
    rating: Rating,
  )
}

fn product_from_json(
  json_string: String,
) -> Result(List(Product), json.DecodeError) {
  let product = {
    use id <- decode.field("id", decode.int)
    use title <- decode.field("title", decode.string)
    use price <- decode.field("price", decode.float)
    use description <- decode.field("description", decode.string)
    use category <- decode.field("category", decode.string)
    use image <- decode.field("image", decode.string)
    use rating <- decode.field("rating", rating_decoder())
    decode.success(Product(
      id,
      title,
      price,
      description,
      category,
      image,
      rating,
    ))
  }
  json.parse(from: json_string, using: decode.list(product))
}

pub fn main() {
  // Prepare a HTTP request record
  let assert Ok(request) = request.to("https://fakestoreapi/products")

  // Send the HTTP request to the server
  use response <- try(
    request
    |> hackney.send,
  )

  // We get a response record back
  response.status
  |> should.equal(200)

 response
  |> response.get_header("content-type")
  |> should.equal(Ok("application/json; charset=utf-8"))


  //io.println(response.body)

  let json_string =
    "[{\"id\":1,\"title\":\"Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops\",\"price\":109.95,\"description\":\"Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday\",\"category\":\"men's clothing\",\"image\":\"https://fakestoreapi/img/81fPKd-2AYL._AC_SL1500_.jpg\",\"rating\":{\"rate\":3.9,\"count\":120}}]"

  case product_from_json(response.body) {
    Ok(products) -> echo products
    Error(_error) -> {
      io.println("Failed to parse JSON: ")
      []
    }
  }


  Ok(Nil)
}

Here is the CURL command:

curl -X GET 'https://fakestoreapi/products'

When I use sample JSON payload it works, but when I use the API response it fails. What am I doing wrong?

Share Improve this question edited Mar 12 at 21:23 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Mar 12 at 18:25 jwesongajwesonga 4,39317 gold badges59 silver badges86 bronze badges 2
  • Fails how? Did you print out the text you got back? Maybe it isn't completely JSON. – Tim Roberts Commented Mar 12 at 18:30
  • I printed out the JSON response and pasted it into jsonviewer.stack.hu to confirm it was valid JSON. I know the call returns a DecodeError but I'm not sure how to display it in the case statement. – jwesonga Commented Mar 12 at 19:05
Add a comment  | 

1 Answer 1

Reset to default 0

I swapped the JSON payload with a different one from https://jsonplaceholder.typicode/todos and modified the code to work with the different payload and it worked. I can only conclude that the initial payload is buggy.

本文标签: gleamMake HTTP API call and decode JSON payloadStack Overflow