-2

i can't seem to get the following code working. The commented lines are sample request bodies, they always come in an array and with a parameter called "type" if i try to parse them i always end up with:

error =  json: cannot unmarshal array into Go value of type main.Entry

unfortunately i can't change the request body itself and have to use it somehow.

package main

import (
       "fmt"
       "github.com/gofiber/fiber/v2"
       "github.com/gofiber/fiber/v2/middleware/logger"
       "github.com/gofiber/fiber/v2/middleware/compress"
       )

func main() {
    app := fiber.New()

    app.Use(logger.New(logger.Config{
    Format: "[${ip}]:${port} ${status} - ${method} ${path} - ${reqHeaders}\n${body}\n",
    }))

    app.Use(compress.New(compress.Config{
    Level: compress.LevelBestSpeed, // 1
    }))


type Entry struct {
    Type string `json:"type"`
    Device string `json:"device"`
    DateString string `json:"dateString"`
    Date string `json:"date"`
    Sgv string `json:"sgv"`
    Delta string `json:"delta"`
    Direction string `json:"direction"`
    Noise string `json:"noise"`
    Filtered string `json:"filtered"`
    Unfiltered string `json:"unfiltered"`
    Rssi string `json:"rssi"`
}


type Entries struct {
    Entries []Entry
    }


    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World!")
    })
// [{"type":"sgv","device":"0EM48R5JQ","dateString":"2023-06-23T22:39:16.000+02:00","date":1687552756000,"sgv":127,"delta":-0.400,"direction":"Flat","noise":1,"filtered":127000,"unfiltered":127000,"rssi":100},{"type":"sgv","device":"0EM48R5JQ","dateString":"2023-06-23T22:40:15.000+02:00","date":1687552815000,"sgv":127,"delta":-0.400,"direction":"Flat","noise":1,"filtered":127000,"unfiltered":127000,"rssi":100}]

// [{"type":"sgv","device":"0EM48R5JQ","dateString":"2023-06-23T22:00:14.000+02:00","date":1687550414000,"sgv":131,"delta":-0.550,"direction":"Flat","noise":1,"filtered":131000,"unfiltered":131000,"rssi":100}]
    app.Post("/api/v1/entries", func(c *fiber.Ctx) error {
    entry := new(Entry)

    if err := c.BodyParser(entry); err != nil {
        fmt.Println("error = ",err)
        return c.SendStatus(500)
    }

    return c.SendStatus(200)
    })

    app.Post("/entries", func(c *fiber.Ctx) error {
    return c.SendString("OK")
    })

    app.Post("/devicestatus", func(c *fiber.Ctx) error {
    return c.SendString("OK")
    })

    app.Post("/treatments", func(c *fiber.Ctx) error {
    return c.SendString("OK")
    })

    app.Listen(":3001")
}

i just want to get an array of structs that i can loop to add to a influx db.

EDIT: thanks for the tip, i changed it to:

package main

import (
    "fmt"
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/fiber/v2/middleware/compress"
    "github.com/gofiber/fiber/v2/middleware/logger"
)

func main() {
    app := fiber.New()

    app.Use(logger.New(logger.Config{
        Format: "[${ip}]:${port} ${status} - ${method} ${path} - ${reqHeaders}\n${body}\n",
    }))

    app.Use(compress.New(compress.Config{
        Level: compress.LevelBestSpeed, // 1
    }))

    type Entry struct {
        Type       string `json:"type"`
        Device     string `json:"device"`
        DateString string `json:"dateString"`
        Date       int64  `json:"date"` // Updated type to int64
        Sgv        int    `json:"sgv"`
        Delta      float64 `json:"delta"`
        Direction  string `json:"direction"`
        Noise      int    `json:"noise"`
        Filtered   int    `json:"filtered"`
        Unfiltered int    `json:"unfiltered"`
        Rssi       int    `json:"rssi"`
    }

    type Entries []Entry

    app.Post("/api/v1/entries", func(c *fiber.Ctx) error {
        entries := new(Entries)
        if err := c.BodyParser(entries); err != nil {
            fmt.Println("error:", err)
            return c.SendStatus(fiber.StatusInternalServerError)
        }

        // Process the entries as needed
        for _, entry := range *entries {
            // Perform actions with each entry
            fmt.Println(entry)
        }

        return c.SendStatus(fiber.StatusOK)
    })

    app.Listen(":3001")
}

it works now.

JRSmile
  • 25
  • 4
  • 1
    The problem has nothing to do with anything being named `type`. Your incoming JSON is an array, but you're trying to unmarshal it into something that isn't an array (slice). – hobbs Jun 23 '23 at 21:36

1 Answers1

0

As @hobbs said, the problem is you are trying to unmarshal an array to an Entry type.

You need to unmarshal it in a []Entry and your Entry type does not have the correct field types, you can use this site to create the correct struct based on your json.

Using the standard json library would look like this.

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

func main() {
    var es []Entry
    if err := json.Unmarshal([]byte(payload), &es); err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(es)
}

type Entry struct {
    Type       string    `json:"type"`
    Device     string    `json:"device"`
    DateString time.Time `json:"dateString"`
    Date       int64     `json:"date"`
    Sgv        int       `json:"sgv"`
    Delta      float64   `json:"delta"`
    Direction  string    `json:"direction"`
    Noise      int       `json:"noise"`
    Filtered   int       `json:"filtered"`
    Unfiltered int       `json:"unfiltered"`
    Rssi       int       `json:"rssi"`
}

const payload = `[{"type":"sgv","device":"0EM48R5JQ","dateString":"2023-06-23T22:39:16.000+02:00","date":1687552756000,"sgv":127,"delta":-0.400,"direction":"Flat","noise":1,"filtered":127000,"unfiltered":127000,"rssi":100},{"type":"sgv","device":"0EM48R5JQ","dateString":"2023-06-23T22:40:15.000+02:00","date":1687552815000,"sgv":127,"delta":-0.400,"direction":"Flat","noise":1,"filtered":127000,"unfiltered":127000,"rssi":100}]`