-2

I'm getting my way around web development with Go's Fiber and I can't seem to get this one thing straight. I have 3 handler functions that are defined in the same package and I'm trying to call 2 of them from inside the 3rd one but without success. It seems like the functions are simply not being executed(as shown by any logs or effect that's supposed to take place).

Am I missing something or you just can't call handler functions like that(I'd like to find the reason) and you need to code actual cURL calls to functions in the same package?

func DeleteComplex2ByID(ctx *fiber.Ctx) error {
    complex2 := &models.Complex2{}
    id := ctx.Params("complex2Id")
    if id == "" {
        return ctx.Status(http.StatusInternalServerError).JSON(&fiber.Map{
            "message": "Complex2 ID cannot be empty on delete",
            "data":    nil})
    }

    complex1s := []models.Complex1{}

    intId, err := strconv.Atoi(id)
    if err != nil {
        fmt.Println(err)
        ctx.Status(http.StatusBadRequest).JSON(&fiber.Map{
            "message": "could not parse id to int",
            "data":    err})
        return err
    }

    query := fmt.Sprintf("SELECT * FROM complex1 WHERE complex2_ids @> '[%d]'", intId)
    err = storage.DB.Raw(query).Scan(&complex1s).Error
    if err != nil {
        fmt.Println(err)
        ctx.Status(http.StatusBadRequest).JSON(&fiber.Map{
            "message": "could not fetch complex",
            "data":    err})
        return err
    }

    for _, complex1 := range complex1s {
        var ids []uint
        err = json.Unmarshal(complex1.Complex2IDs, &ids)
        if err != nil {
            fmt.Println(err)
        }
        idx := slices.Index(ids, uint(intId))
        newComplexIDs := slices.Delete(ids, idx, idx+1)

        ctx.Context().ResetBody()
        ctx.Set("complexId", strconv.FormatUint(uint64(complex1.ID), 10))

        if len(newComplexIDs) == 0 {
            DeleteComplexByID(ctx)
        } else {
            updateComplex2IDs := map[string]interface{}{
                "Complex2IDs": newComplexIDs}

            updateComplex2IDsJSON, err := json.Marshal(updateComplex2IDs)
            if err != nil {
                ctx.Status(http.StatusBadRequest).JSON(&fiber.Map{
                    "message": "blah blah",
                    "data":    err})
                return err
            }
            UpdateComplexByID(ctx)
            }
        }
    }

    res := storage.DB.Unscoped().Delete(complex2, id)
    if res.Error != nil || res.RowsAffected == 0 {
        ctx.Status(http.StatusBadRequest).JSON(&fiber.Map{
            "message": "could not delete Complex2, check if Complex2 with ID " + id + " exists",
            "data":    res.Error})
        return res.Error
    }
    ctx.Status(http.StatusOK).JSON(&fiber.Map{"message": "Complex2 deleted successfully"})
    return nil
}

The use case is: when deleting a Complex2 entry I also want to delete all references to it from any Complex1 entries; if a Complex1's Complex2 reference list is empty also delete that Complex1 entry. Both DeleteComplexByID and UpdateComplexByID work when sending delete/update cURL requests. Additional Info: This is how DeleteComplexByID looks like, UpdateComplexByID looks very similar.

func DeleteComplexByID(ctx *fiber.Ctx) error {
    complex := &models.Complex1{}
    id := ctx.Params("complexId")
    if id == "" {
        return ctx.Status(http.StatusInternalServerError).JSON(&fiber.Map{
            "message": "complex ID cannot be empty on delete",
            "data":    nil})
    }

    res := storage.DB.Unscoped().Delete(complex, id)
    if res.Error != nil || res.RowsAffected == 0 {
        ctx.Status(http.StatusBadRequest).JSON(&fiber.Map{
            "message": "could not delete complex, check if complex with ID " + id + " exists",
            "data":    res.Error})
        return res.Error
    }
    ctx.Status(http.StatusOK).JSON(&fiber.Map{"message": "complex deleted successfully"})
    return nil
}

Routing

func SetupTestComplexRoutes(router fiber.Router) {
    complex1 := router.Group("/complex1")
    complex1.Post("/", testComplexHandler.CreateComplex)
    complex1.Get("/", testComplexHandler.GetComplexes)
    complex1.Get("/:complexId", testComplexHandler.GetComplexByID)
    complex1.Delete("/:complexId", testComplexHandler.DeleteComplexByID)
    complex1.Put("/:complexId", testComplexHandler.UpdateComplexByID)
    complex2 := router.Group("/complex2")
    complex2.Post("/", testComplexHandler.CreateComplex2)
    complex2.Get("/", testComplexHandler.GetComplex2)
    complex2.Get("/:complex2Id", testComplexHandler.GetComplex2ByID)
    complex2.Delete("/:complex2Id", testComplexHandler.DeleteComplex2ByID)
    complex2.Put("/:complex2Id", testComplexHandler.UpdateComplex2ByID)
}

Request

    curl --location --request DELETE 'http://localhost:8080/api/complex2/1'
  • If you write all your besiness into your handlers you will stuck with these kind of imposibilities. Instead you could vae some buesiness layer and call that layer from the handlers. So you don't have to call another endpoint – Eldar Aug 16 '23 at 12:18
  • appreciate the comment @Eldar, indeed I should've separated the business logic from the handlers. however I was more curios about why calling the other handlers fails from a Fiber perspective – greedo_desu Aug 16 '23 at 15:58

0 Answers0