primer intento de servicio para acortar urls

This commit is contained in:
2026-03-12 00:13:46 -03:00
commit 1b3ae43d61
9 changed files with 161 additions and 0 deletions

0
.env Normal file
View File

5
dto/reqbody.go Normal file
View File

@@ -0,0 +1,5 @@
package dto
type ReqBody struct {
LongUrl string `json:"longUrl"`
}

12
go.mod Normal file
View File

@@ -0,0 +1,12 @@
module url-short
go 1.25.7
require (
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-sqlite3 v1.14.34 // indirect
golang.org/x/text v0.35.0 // indirect
gorm.io/driver/sqlite v1.6.0 // indirect
gorm.io/gorm v1.31.1 // indirect
)

12
go.sum Normal file
View File

@@ -0,0 +1,12 @@
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk=
github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=

39
main.go Normal file
View File

@@ -0,0 +1,39 @@
package main
import (
"fmt"
"net/http"
"os"
"url-short/models"
"url-short/routes"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func main() {
fmt.Println("Iniciando url-short")
db, err := gorm.Open(sqlite.Open("shorturls.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
fmt.Println("Se conecto a la base de datos")
db.AutoMigrate(&models.Url{})
http.HandleFunc("/url", func(w http.ResponseWriter, r *http.Request){
routes.Url(w, r, db)
})
port := ":8080"
if envPort := os.Getenv("PORT"); envPort != "" {
port = ":" + envPort
}
fmt.Println("Servidor escuchando en puerto: http://localhost"+ port)
err = http.ListenAndServe(port, nil)
if err != nil {
panic("Error starting server: " + err.Error())
}
}

10
models/url.go Normal file
View File

@@ -0,0 +1,10 @@
package models
import "time"
type Url struct {
Shorturl string `gorm:"primaryKey"`
// Id uint64 `gorm: "primaryKey;autoIncrement"`
Longurl string `gorm:"uniqueIndex:idx_lurl"`
Time time.Time `gorm:"autoCreateTime"`
}

3
readme.md Normal file
View File

@@ -0,0 +1,3 @@
# Config
si se necesita especificar un puerto use la variable de entorno `PORT`
Ej, `PORT=8081 ./url-short`

47
repository/CrearUrl.go Normal file
View File

@@ -0,0 +1,47 @@
package repository
import (
"crypto/sha3"
"fmt"
"url-short/models"
"gorm.io/gorm"
)
func CrearUrl(longURL string, db *gorm.DB) (string, error) {
// checkeamos por longurl repetida
counturl := int64(0)
result := db.Model(&models.Url{}).Where("longurl = ?", longURL).Count(&counturl)
if result.Error != nil {
return "", result.Error
}
if counturl != 0 {
println(1)
var short models.Url
result = db.Model(&short).Where("longurl = ?", longURL).Select("shorturl").First(&short)
if result.Error != nil {
return "", result.Error
}
return short.Shorturl, nil
}
// shortURL := base64.StdEncoding.EncodeToString([]byte(longURL))[:10]
sha := sha3.New224()
sha.Write([]byte(longURL))
shortURL := fmt.Sprintf("%x", sha.Sum(nil))[:10]
result = db.Model(&models.Url{}).Where("shorturl = ?", shortURL).Count(&counturl)
if result.Error != nil {
return "", result.Error
}
if counturl != 0 {
return shortURL, nil
}
result = db.Create(&models.Url{Longurl: longURL, Shorturl: shortURL})
if result.Error != nil {
return "", result.Error
}
return shortURL, nil
}

33
routes/url.go Normal file
View File

@@ -0,0 +1,33 @@
package routes
import (
"encoding/json"
"net/http"
"url-short/dto"
"url-short/repository"
"gorm.io/gorm"
)
func Url(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
if r.Method == http.MethodPost {
var reqBody dto.ReqBody
err := json.NewDecoder(r.Body).Decode(&reqBody)
if err != nil {
http.Error(w, "Error: ", http.StatusBadRequest)
return
}
shortUrl, err := repository.CrearUrl(reqBody.LongUrl, db)
if err != nil {
http.Error(w, "Error: "+err.Error(), http.StatusBadRequest)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"shortUrl": shortUrl,
})
}else{
http.Error(w, "404", http.StatusBadGateway);
}
}