0
\$\begingroup\$

I have an API Swagger generated, I'm not satisfied with how I'm handling my part of the contract e.g. how I have constructed my db and handlers modules.

Specially how I'm dealing the the database connection, can this not be made more robust by using interfaces. For simplicity I'm just including one implemented endpoint.

// This file is safe to edit. Once it exists it will not be overwritten

package restapi

import (
    "crypto/tls"
    "net/http"

    "github.com/go-openapi/errors"
    "github.com/go-openapi/runtime"
    "github.com/go-openapi/runtime/middleware"
    log "github.com/sirupsen/logrus"
    "hairdoo.com/m/v2/handlers"
    "hairdoo.com/m/v2/models"
    "hairdoo.com/m/v2/restapi/operations"
    "hairdoo.com/m/v2/restapi/operations/company"
    "hairdoo.com/m/v2/restapi/operations/employee"
)

//go:generate swagger generate server --target ../../hairdoo --name Hairdoo --spec ../swagger.yml --principal interface{}

//var db *gorm.DB

func init() {
    // Log as JSON instead of the default ASCII formatter.
    /*log.SetFormatter(&log.JSONFormatter{
        TimestampFormat: "2006-01-02 15:04:05",
        //PrettyPrint:     true,
    })*/

    // Output to stdout instead of the default stderr
    // Can be any io.Writer, see below for File example
    //log.SetOutput(os.Stdout)

    log.SetFormatter(&log.TextFormatter{
        DisableColors: false,
        FullTimestamp: true,
    })

    // Only log the warning severity or above.
    //log.SetLevel(log.WarnLevel)
    log.SetLevel(log.InfoLevel)
}

func configureFlags(api *operations.HairdooAPI) {
    // api.CommandLineOptionsGroups = []swag.CommandLineOptionsGroup{ ... }
}

func configureAPI(api *operations.HairdooAPI) http.Handler {
    // configure the api here
    api.ServeError = errors.ServeError

    // Set your custom logger if needed. Default one is log.Printf
    // Expected interface func(string, ...interface{})
    //
    // Example:
    //api.Logger = log.Printf

    api.UseSwaggerUI()
    // To continue using redoc as your UI, uncomment the following line
    // api.UseRedoc()

    api.JSONConsumer = runtime.JSONConsumer()
    //api.UrlformConsumer = runtime.DiscardConsumer

    api.JSONProducer = runtime.JSONProducer()

    api.CompanyAddCompanyHandler = company.AddCompanyHandlerFunc(func(params company.AddCompanyParams) middleware.Responder {
        //log.Debugf("Add commpay Handler Called")
        //log.Infof("Payload Data : %v", params.Body)

        response, err := handlers.AddCompany(params)
        if err != nil {
            return company.NewAddCompanyBadRequest().WithPayload(&models.ErrorReponse400{
                Error: err.Error(),
            })
        }

        return company.NewAddCompanyCreated().WithPayload(response)
    })

handlers/company.go

package handlers

import (
    "hairdoo.com/m/v2/db"
    "hairdoo.com/m/v2/models"
    "hairdoo.com/m/v2/restapi/operations/company"
)

func AddCompany(params company.AddCompanyParams) (*models.Company, error) {
    result, err := db.AddCompany(params.Body)
    if err != nil {
        return nil, err
    }

    return result, nil
}

db/company.go

import (
    "fmt"
    "time"

    "gorm.io/gorm"
    "hairdoo.com/m/v2/models"
)

type Company struct {
    gorm.Model
    Name           string `gorm:"uniqueIndex"`
    Phone          string
    Email          string
    ContatctPerson string
    CategoryID     int
    Category       *Category
    Status         string
}

type Category struct {
    ID   int
    Name string `gorm:"uniqueIndex"`
}

func AddCompany(companyObj *models.Company) (*models.Company, error) {
    db := Open()
    var result *gorm.DB

    category := &Category{}

    db.Where("name = ?", companyObj.Category.Name).First(category)

    company := convertToDBCompany(companyObj, false)
    if category.ID != 0 {
        result = db.Exec("INSERT INTO companies (created_at, updated_at, name, phone, email, contatct_person, category_id) values (?, ?, ?, ?, ?, ?, ?);",
            time.Now(), time.Now(), companyObj.Name, companyObj.Phone, companyObj.Email, companyObj.ContatctPerson, category.ID)
    } else {
        result = db.Create(company)
    }

    if result.RowsAffected < 1 {
        return nil, result.Error
    }

    // add employee to db if object present
    var employees []*models.EmployeeItems0
    if companyObj.Employee != nil {
        for _, employeeInput := range companyObj.Employee {
            result, err := AddEmployee(employeeInput)
            if err != nil {
                return nil, err
            }
            employees = append(employees, result)
        }
    }

    return convertToModelCompany(company, employees), nil
}

database.go

package db

import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

func Open() *gorm.DB {
    connString := "root:12345@tcp(0.0.0.0:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(connString), &gorm.Config{})
    if err != nil {
        panic(err)
    }

    db.AutoMigrate(Company{}, Category{}, Employee{})

    return db
}
```
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.