short/internal/api/handler.go

60 lines
1.4 KiB
Go

package api
import (
"context"
"errors"
"fmt"
"github.com/babariviere/short/internal/db"
"github.com/babariviere/short/internal/oas"
"github.com/babariviere/short/internal/url"
"github.com/jackc/pgx/v5"
)
var _ oas.Handler = (*handler)(nil)
type handler struct {
serverUrl string
queries *db.Queries
}
func NewHandler(serverUrl string, queries *db.Queries) *handler {
return &handler{
serverUrl: serverUrl,
queries: queries,
}
}
func (h *handler) RedirectLongURL(ctx context.Context, params oas.RedirectLongURLParams) (oas.RedirectLongURLRes, error) {
res, err := h.queries.GetURLByHash(ctx, params.Hash)
switch {
case errors.Is(err, pgx.ErrNoRows):
return &oas.RedirectLongURLNotFound{}, nil
case err != nil:
return nil, fmt.Errorf("unable to fetch URL by hash: %w", err)
}
return &oas.RedirectLongURLTemporaryRedirect{
Location: oas.NewOptString(res.LongUrl),
}, nil
}
func (h *handler) CreateShortURL(ctx context.Context, req *oas.CreateShortURLReq) (oas.CreateShortURLRes, error) {
hash, err := url.GenerateHash(req.URL)
if err != nil {
return nil, fmt.Errorf("failed to generate hash for url %s: %w", req.URL, err)
}
res, err := h.queries.InsertURL(ctx, db.InsertURLParams{
Hash: hash,
LongUrl: req.URL,
})
if err != nil {
return nil, fmt.Errorf("failed to insert url: %w", err)
}
return &oas.CreateShortURLCreated{
Shorten: h.serverUrl + "/" + res.Hash,
}, nil
}