R2 от Cloudflare  —  мощная, но простая платформа для безопасного хранения файлов.

Чтобы разобраться в процессе загрузки файлов Go в хранилище Cloudflare R2, требуется немало времени. Упрощаем задачу, предлагая вашему вниманию это руководство.

Пройдем процесс поэтапно, снабжая фрагменты кода пояснениями, весь код  —  в конце.

Этап 1. Настройка среды

Сначала установим необходимые пакеты, для кода на Go это SDK-пакет AWS:

go get -u github.com/aws/aws-sdk-go-v2

Этап 2. Определение структуры S3Service

Прежде чем переходить к деталям реализации, инкапсулируем информацию о клиенте S3 и корзине в структуру S3Service, вокруг которой эффективно выстраиваются код и взаимодействия с хранилищем Cloudflare R2:

type S3Service struct {
s3Client *s3.Client // Клиент S3 AWS для взаимодействия с сервисом
bucket string // Название корзины в хранилище Cloudflare R2
}

Этап 3. Инициализация сервиса Cloudflare R2

Теперь реализуем функцию NewR2Service, задав конфигурацию SDK-пакета AWS с учетными данными и конечной точкой:

// Функция для инициализации сервиса Cloudflare R2
func NewR2Service() (*S3Service, error) {
// Заменяем эти значения учетными данными для Cloudflare R2
account := "YOUR_ACCOUNT_ID"
accessKey := "YOUR_ACCESS_KEY_ID"
secretKey := "YOUR_SECRET_ACCESS_KEY"
bucket := "YOUR_BUCKET_NAME"

// Создаем пользовательский резолвер для конечной точки R2
r2Resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{
URL: fmt.Sprintf("https://%s.r2.cloudflarestorage.com", account),
}, nil
})

// С помощью пользовательского резолвера загружаем конфигурацию AWS
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithEndpointResolverWithOptions(r2Resolver),
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")),
config.WithRegion("apac"),
)
if err != nil {
return nil,err
}

// Создаем новый клиент S3
s3Client := s3.NewFromConfig(cfg)

// Возвращаем новый экземпляр S3Service, инициализированный клиентом S3 и названием корзины
return &S3Service{
s3Client: s3Client,
bucket: bucket,
}, nil
}

Этап 4. Загрузка файлов в хранилище Cloudflare R2

В методе UploadFileToR2 перед началом процесса загрузки указываются ключ файла, содержимое и тип содержимого:

// Функция для загрузки файла в хранилище Cloudflare R2
func (s *S3Service) UploadFileToR2(ctx context.Context, key string, file []byte) error {
// Создаем «PutObjectInput» с указанными корзиной, ключом, содержимым файла и типом содержимого
input := &s3.PutObjectInput{
Bucket: aws.String(s.bucket),
Key: aws.String(key),
Body: bytes.NewReader(file),
ContentType: aws.String("image/jpeg"), // Задаем тип содержимого «image/jpeg», при необходимости меняем
}

// Загружаем файл в хранилище Cloudflare R2
_, err := s.s3Client.PutObject(ctx, input)
if err != nil {
return err
}

return nil
}

Этап 5. Загрузка файла

Создадим функцию main, которой инициализируется сервис Cloudflare R2 и загружается файл:

func main() {
// Инициализируем сервис Cloudflare R2
s3Service, err := NewR2Service()
if err != nil {
log.Fatal(err)
}

// Загружаем файл
err = s3Service.UploadFileToR2(context.TODO(), "image.jpg", []byte("test"))
if err != nil {
log.Fatal(err)
}
}

Заключение

Вот так, снабдив фрагменты кода пояснениями, мы получили четкое руководство по беспроблемной интеграции в приложения процесса загрузки файлов Go на Cloudflare R2.

Полный код:

package main

import (
"bytes"
"context"
"fmt"
"log"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)

type S3Service struct {
s3Client *s3.Client
bucket string
}

// Функция для инициализации сервиса Cloudflare R2
func NewR2Service() (*S3Service, error) {
// Заменяем эти значения учетными данными для Cloudflare R2
account := "YOUR_ACCOUNT_ID"
accessKey := "YOUR_ACCESS_KEY_ID"
secretKey := "YOUR_SECRET_ACCESS_KEY"
bucket := "YOUR_BUCKET_NAME"

// Создаем пользовательский резолвер для конечной точки R2
r2Resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{
URL: fmt.Sprintf("https://%s.r2.cloudflarestorage.com", account),
}, nil
})

// С помощью пользовательского резолвера загружаем конфигурацию AWS
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithEndpointResolverWithOptions(r2Resolver),
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")),
config.WithRegion("apac"),
)
if err != nil {
return nil,err
}

// Создаем новый клиент S3
s3Client := s3.NewFromConfig(cfg)

return &S3Service{
s3Client: s3Client,
bucket: bucket,
}, nil

}

// Функция для загрузки файла в хранилище Cloudflare R2
func (s *S3Service) UploadFileToR2(ctx context.Context, key string, file []byte) error {
input := &s3.PutObjectInput{
Bucket: aws.String(s.bucket),
Key: aws.String(key),
Body: bytes.NewReader(file),
ContentType: aws.String("image/jpeg"),
}

// Загружаем файл
_, err := s.s3Client.PutObject(ctx, input)
if err != nil {
return err
}

return nil
}

func main() {
// Инициализируем сервис Cloudflare R2
s3Service, err := NewR2Service()
if err != nil {
log.Fatal(err)
}

// Загружаем файл
err = s3Service.UploadFileToR2(context.TODO(), "image.jpg", []byte("test"))
if err != nil {
log.Fatal(err)
}
}

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Matthew Araujo: Uploading Files to Cloudflare R2 Storage: A Simple Guide

Предыдущая статьяЧистая архитектура фронтенда: 7 советов для достижения успеха
Следующая статьяСоздание кастомизированного кругового загрузчика в Jetpack Compose: изучение Android Canvas и анимации