diff --git a/README.md b/README.md index 4af88f1..c2204d3 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,8 @@ python -m worker # worker ### 6. Test the API ```bash -curl -X POST http://localhost:8080/api/v1/assets/upload \ +curl -X POST http://localhost:8080/api/v1/storage/presign \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "fileName": "image.jpg", @@ -201,7 +202,7 @@ kubectl apply -f deploy/k8s/ ### Upload Asset -**Endpoint:** `POST /api/v1/assets/upload` +**Endpoint:** `POST /api/v1/storage/presign` **Request:** ```json @@ -215,15 +216,18 @@ kubectl apply -f deploy/k8s/ **Response:** ```json { - "uploadUrl": "https:///...", - "assetId": "550e8400-e29b-41d4-a716-446655440000", - "method": "PUT", - "headers": { - "Content-Type": "image/jpeg" - }, - "objectPath": "media/raw/550e8400-e29b-41d4-a716-446655440000", - "publicUrl": "https:///...", - "expiresAt": 1702468800 + "status": "success", + "data": { + "uploadUrl": "https:///...", + "assetId": "550e8400-e29b-41d4-a716-446655440000", + "method": "PUT", + "headers": { + "Content-Type": "image/jpeg" + }, + "objectPath": "media/raw/550e8400-e29b-41d4-a716-446655440000", + "publicUrl": "https:///...", + "expiresAt": 1702468800 + } } ``` @@ -231,16 +235,18 @@ kubectl apply -f deploy/k8s/ ### Mark Asset as Uploaded -**Endpoint:** `POST /api/v1/assets/{assetId}/uploaded` +**Endpoint:** `POST /api/v1/assets/{assetId}/complete` **Response:** ```json { - "message": "Asset marked as uploaded", - "assetId": "550e8400-e29b-41d4-a716-446655440000" + "status": "success", + "message": "Asset marked as uploaded" } ``` +> Both endpoints require an `Authorization: Bearer ` header. + ## 🔧 Development ### Project Structure diff --git a/internal/router/router.go b/internal/router/router.go index 64bb72d..d60d68e 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -13,8 +13,8 @@ import ( "github.com/jmoiron/sqlx" "github.com/rndmcodeguy20/mpiper/internal/config" "github.com/rndmcodeguy20/mpiper/internal/handler" - appMiddleware "github.com/rndmcodeguy20/mpiper/internal/middleware" "github.com/rndmcodeguy20/mpiper/internal/metrics" + appMiddleware "github.com/rndmcodeguy20/mpiper/internal/middleware" "github.com/rndmcodeguy20/mpiper/internal/repository" "github.com/rndmcodeguy20/mpiper/internal/service" applogger "github.com/rndmcodeguy20/mpiper/pkg/logger" @@ -153,7 +153,7 @@ func NewRouter(cfg config.EnvConfig, db *sqlx.DB, m *metrics.Metrics) *chi.Mux { r.Route("/assets", func(r chi.Router) { r.Use(appMiddleware.AuthMiddleware(logger)) - r.Get("/{assetID}/complete", assetHandler.MarkAssetUploaded) + r.Post("/{assetID}/complete", assetHandler.MarkAssetUploaded) }) }) diff --git a/internal/service/asset.go b/internal/service/asset.go index 8e1d48a..4a2a6d6 100644 --- a/internal/service/asset.go +++ b/internal/service/asset.go @@ -27,6 +27,10 @@ type AssetService interface { MarkAssetUploaded(ctx context.Context, assetID uuid.UUID) error } +// presignExpiry is how long returned upload URLs remain valid; it must stay in +// sync with the expiry the storage provider signs into the URL. +const presignExpiry = 5 * time.Minute + type assetService struct { assetRepo repository.AssetRepository logger *zap.Logger @@ -105,7 +109,7 @@ func (s *assetService) CreateAsset(ctx context.Context, request models.UploadAss signedUrl, err := s.storageClient.GeneratePresignedURL(spanStorageCtx, s.bucket, objectKey, &storagex.PresignedURLOptions{ Method: "PUT", ContentType: request.ContentType, - ExpiresInSeconds: 60 * 5, // 5 minutes + ExpiresInSeconds: int64(presignExpiry.Seconds()), }) spanStorage.End() @@ -170,9 +174,9 @@ func (s *assetService) CreateAsset(ctx context.Context, request models.UploadAss AssetID: assetID.String(), Method: "PUT", Headers: map[string]string{"Content-Type": request.ContentType}, - ObjectPath: request.FileName, + ObjectPath: objectKey, PublicUrl: publicUrl, - ExpiresAt: 60 * 5, // 5 minutes + ExpiresAt: time.Now().Add(presignExpiry).Unix(), }, nil } diff --git a/pkg/utils/response.go b/pkg/utils/response.go index 85c2673..f41be84 100644 --- a/pkg/utils/response.go +++ b/pkg/utils/response.go @@ -46,7 +46,7 @@ func WriteErrorResponse(w http.ResponseWriter, err error) { } w.WriteHeader(apiErr.StatusCode) _ = json.NewEncoder(w).Encode(map[string]interface{}{ - "success": false, + "status": "error", "message": apiErr.Message, "error": map[string]interface{}{ "code": apiErr.Code,