Статья, главным образом, состоит из двух частей: описания проблемы и описания ее решения. Если сама проблема вас не интересует, первый раздел можно пропустить без ущерба для себя либо животных. Или вообще можно всю статью пропустить.
Идентифицируем проблему
В начале вас ждет небольшое, но важное вступление. Оно поможет увидеть как я докопался до сути проблемы и затем, перешел к ее решению.
Я разработчик и я предпочитаю проводить время со своим компьютером. Но все же иногда мне нужно выходить из дома, вы знаете, делать все те вещи, что делают другие люди. И вот однажды, возвращаясь домой со своей сумкой продуктов я увидел некоторую картину: группа людей с плакатами на которых написано “Save animals”. Как я уже говорил, я разработчик и прекрасно понимаю английский. Они, очевидно, хотели сохранить животных. И раз столько людей собрались вместе — это очень серьезная проблема, подумал я.
Эти люди не знали кто только что прошел мимо них. Я разработчик — один из тех людей которые делают мир лучше. И я намерен решить их проблему.
Хотя было кое-что, что воспрепятствовало мне тут же приступить к самому решению. Этим фактором было непонимание данной проблемы. Я ведь с детства интересовался компьютерами, а животные меня не слишком привлекали. Но это не беда, ведь у нас есть ChatGPT. Всего-то нужно задать ему правильный вопрос. И вот полученный ответ, понятный мне как инженеру:
Если подойти к этому вопросу чисто с технической стороны, я бы предположил что термин “животные” может относиться к набору данных или категорий в компьютерной системе. В этом контексте, “сохранить животных” может означать сохранение и защиту информации или данных внутри приложения или базы данных.
ChatGPT
Правда ChatGPT замечательная вещь? Немного помучал его вопросами, и он выдал нужный мне ответ. Теперь все стало понятно: этим людям нужно решение, которое позволит им сохранять изображения котов, собак или других животных.
Ну что же, проблема идентифицирована и мы наконец-то можем приступить к ее решению.
Реализуем решение
Давайте определимся с требованиями к нашему приложению. Наш сервис сохранения животных будет доступен по HTTP. Он будет принимать POST запрос с одним или несколькими файлами изображений животных. Также мы будем использовать путь нашего URL для целей категоризации изображений животных.
В итоге, моя инфраструктура будет выглядеть наподобие той что на диаграмме ниже.
Первое чем было решено заняться — это процессинг файлов. Естественно, я имею вполне нормальное желание сделать все быстро. Всю работу связанную с файлам я скину на небольшой сервис под названием Capyfile, код которого можно найти на GitHub. Ему нужно вскормить небольшой конфигурационный файл, которых скажет что я хочу делать с загружаемыми файлам. Мой конфиг выглядит так:
{ "version": "1.0", "name": "upload", "processors": [ { "name": "animal", "operations": [ { "name": "file_size_validate", "params": { "maxFileSize": { "sourceType": "http_header", "source": "X-Capyfile-FileSizeValidate-MaxFileSize" } } }, { "name": "file_type_validate", "params": { "allowedMimeTypes": { "sourceType": "http_header", "source": "X-Capyfile-FileTypeValidate-AllowedMimeTypes" } } }, { "name": "metadata_cleanup" }, { "name": "image_convert", "params": { "toMimeType": { "sourceType": "value", "source": "image/jpeg" }, "quality": { "sourceType": "value", "source": "high" } } }, { "name": "s3_upload", "params": { "accessKeyId": { "sourceType": "secret", "source": "aws_access_key_id" }, "secretAccessKey": { "sourceType": "secret", "source": "aws_secret_access_key" }, "endpoint": { "sourceType": "env_var", "source": "AWS_ENDPOINT" }, "region": { "sourceType": "env_var", "source": "AWS_REGION" }, "bucket": { "sourceType": "http_header", "source": "X-Capyfile-S3Upload-Bucket" } } } ] } ] }
Из него ясно, что я хочу сделать с каждым загруженным файлом:
-
Проверить размер файла
-
Проверить MIME-тип файла
-
Очистить метаданные файла
-
Конвертировать файл в JPEG формат
-
Сохранить файл в совместимое с S3 хранилище
Некоторые из необходимых параметров будут пробрасываться из приложения которое я напишу далее. Другие же параметры будут получены из окружения Docker контейнера.
Теперь финальная часть — написание приложения, которое будет содержит некую бизнес-логику удовлетворяющую моим требованиям. По большей части, оно будет проксировать запросы, попутно обогащая их нужными параметрами. Эти параметры будут говорить Capyfile как проверять файлы и где эти файлы сохранять.
package main import ( "net/http" "net/http/httputil" "net/url" "strconv" "strings" ) const ( Byte = 1 << (iota * 10) KiByte MiByte GiByte TiByte PiByte EiByte ) func main() { http.HandleFunc("/", capyfileProxyHandler) http.ListenAndServe(":8080", nil) } func capyfileProxyHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } path := strings.Split( strings.TrimLeft(r.URL.Path, "/"), "/") if len(path) != 1 { w.WriteHeader(http.StatusNotFound) return } animal := path[0] if animal == "seagull" { w.WriteHeader(http.StatusForbidden) return } if animal == "capybara" { r.Header.Set( "X-Capyfile-FileSizeValidate-MaxFileSize", strconv.Itoa(100*MiByte)) r.Header.Set( "X-Capyfile-FileTypeValidate-AllowedMimeTypes", `["image/jpeg", "image/png", "image/gif", "image/bmp", "image/webp", "image/heic", "image/heif"]`) } else { r.Header.Set( "X-Capyfile-FileSizeValidate-MaxFileSize", strconv.Itoa(1*MiByte)) r.Header.Set( "X-Capyfile-FileTypeValidate-AllowedMimeTypes", `["image/jpeg", "image/png"]`) } // We assume that all the necessary buckets are already created // or can be created on the fly. r.Header.Set("X-Capyfile-S3Upload-Bucket", animal) r.URL.Path = "/upload/animal" proxy := httputil.NewSingleHostReverseProxy(&url.URL{ Scheme: "http", Host: "localhost:8024", }) proxy.ServeHTTP(w, r) }
Запускаем и тестируем
Первым делом, мы запустим Capyfile сервер:
docker run --rm \ --name capyfile_server \ --mount type=bind,source=./service-definition.json,target=/etc/capyfile/service-definition.json \ --env CAPYFILE_SERVICE_DEFINITION_FILE=/etc/capyfile/service-definition.json \ --env AWS_ENDPOINT=s3.amazonaws.com \ --env AWS_REGION=us-west-1 \ --secret aws_access_key_id \ --secret aws_secret_access_key \ -p 8024:8024 \ capyfile/capysvr:latest
Затем запускаем наше приложение:
go run animal_saver.go
Теперь все готово для сохранения животных в S3 хранилище.
Заключение
Здесь вы могли увидеть как легко я решил проблему сохранения животных.
Также вы не могли не заметить, что Capyfile существенно ускорил разработку данного решения. Поэтому хочу побудить вас оказать этому проекту свою поддержку. С благодарностью принимаются дельные мысли, идеи, пул-реквесты.

ссылка на оригинал статьи https://habr.com/ru/articles/753966/
Добавить комментарий