백엔드 도전기

Imgbb를 활용하여 이미지 호스팅 해보기

포켓몬마스터가될테야 2025. 5. 23. 17:37
  1. 이미지 호스팅이란?
  2. ImgBB
    1. ImgBB 소개
    2. 왜 ImgBB를 선택하였는지
  3. 사용 방법
  4. 프로젝트 적용
  5. 유의할 점

 

1. 이미지 호스팅이란?

An image hosting service allows individuals to upload images to an Internet website. The image host will then store the image onto its server, and show the individual different types of code to allow others to view that image.
- wikipedia

 

 위키피디아에서 가져온 위 글대로 이미지 호스팅이란 이미지를 인터넷 웹사이트에 올여서 해당 서버에 저장한 후 url 등을 사용하여 이미지를 사용할 수 있도록 해주는 서비스이다.

 

 프로젝트에서 관리자 페이지 구현을 맡으며 CRUD 중 C, U 부분에서 이미지를 업로드하는 기능이 필요했다.

처음에는 강의에서 배운대로 로컬 폴더 안에 해당 이미지를 저장해서 addResourceHandlers()를 사용하여 특정 url로 접근하면 파일에 접근할 수 있도록 했었는데 이 서비스를 확장하고, 더 많은 데이터들을 넣는다고 생각을 했을 때, 위와 같은 방식은 너무 무거워지고, 유지관리와 확장성 측면에서 한계가 있다고 생각했다.

 

 따라서 이미지 호스팅을 사용해보자!! 라고 다짐함

 

2. ImgBB 

1. 소개

https://imgbb.com/

 

무료 이미지 호스팅 / 이미지 업로드

이미지를 업로드 하고공유해보세요. 원하는 곳 어디든 끌어놓기로 이미지를 바로 업로드해보세요.(이미지당 32 MB 가능) 다이렉트 링크, BBCode 및 HTML 미리보기등을 제공해드립니다.

imgbb.com

 

ImgBB는 무료로 이미지 호스팅을 지원해주는 사이트로, 무료로도 32MB까지의 이미지도 업로드 할 수 있다.

 

2. 왜 ImgBB를 썼는가?

api를 찾는 조건은 단 두 가지였다. 

1. 무료일것

2. 나같은 초짜도 사용할 수 있을 정도로 쉬운 구조를 가지고 있을 것.

 

그러며 여러 api를 찾아 다녔는데 확실히 유료 서비스가 많았다. 그 중 무료로 지원하는 api들을 몇개 찾아냈다.

처음으로 Imgur를 사용할까 했는데 해당 서비스는 정책이 바뀌면서 호스팅으로는 적합하지 않다고 한다. 

ImgBB는 일단 무료로 사용가능하고, 간단하게 파일만 파라미터에 넣어 전송하면 사용 가능해서 초짜인 나에게 괜찮은 서비스라고 생각했다.

 

더보기

개발자라면 왜 이것을 사용했는가? 왜 다른 api를 사용하지 않았는가? 와 같은 Why가 중요하다고 해서 최대한 이것을 적어보려고 하는데 너무 어렵다.

그냥 이거 쓸까? 하고 사용하기도 해서 내가 이렇게 실력이 안 느나 보다... 화이팅 화이팅

 

3. 사용 방법

1. ImgBB에 회원 가입 후, API 메뉴로 들어간다.

2. API key를 받는다.

3. https://api.imgbb.com/1/upload 로 apiKey와 업로드할 이미지 파일과 함께 Post 요청을 보낸다.

 

우선 Postman을 사용하여 사용해보았다.

 

위와 같이 요청을 보냈을 때,

{
    "data": {
        "id": "F4bCqmw3",
        "title": "dog",
        "url_viewer": "https://ibb.co/F4bCqmw3",
        "url": "https://i.ibb.co/fdYLGqpF/dog.png",
        "display_url": "https://i.ibb.co/N26bntjC/dog.png",
        "width": 787,
        "height": 700,
        "size": 22614,
        "time": 1747987747,
        "expiration": 0,
        "image": {
            "filename": "dog.png",
            "name": "dog",
            "mime": "image/png",
            "extension": "png",
            "url": "https://i.ibb.co/fdYLGqpF/dog.png"
        },
        "thumb": {
            "filename": "dog.png",
            "name": "dog",
            "mime": "image/png",
            "extension": "png",
            "url": "https://i.ibb.co/F4bCqmw3/dog.png"
        },
        "medium": {
            "filename": "dog.png",
            "name": "dog",
            "mime": "image/png",
            "extension": "png",
            "url": "https://i.ibb.co/N26bntjC/dog.png"
        },
        "delete_url": "https://ibb.co/F4bCqmw3/70e9334a1ba6694100845b1e67b978e3"
    },
    "success": true,
    "status": 200
}

 

으로 응답이 온 것을 볼 수 있다.

제대로 작동하는 것을 확인 했으니 이제 프로젝트에 적용해보자!!

 

 

4. 프로젝트 적용

일단 반성하자. GPT가 코드 짜주었다.

이러면 안 된다는 걸 알지만... 이래서 내 실력이 안 느는 건데 일단 구현이 되긴 했다

 

@Component
@RequiredArgsConstructor
public class ImgUploadTemplate {

    @Value("${upload.imgbb.api-key}")
    private String apiKey;

    @Value("${upload.imgbb.url}")
    private String url;

    private WebClient webClient;

    @PostConstruct
    private void initWebClient() {
        this.webClient = WebClient.builder()
            .baseUrl(url)
            .build();
    }

    public String uploadImage(MultipartFile file, String name) throws IOException {
        String base64Image = Base64.getEncoder().encodeToString(file.getBytes());

        String response = webClient.post()
            .uri(uriBuilder -> uriBuilder.queryParam("key", apiKey).build())
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(BodyInserters
                .fromFormData("image", base64Image)
                .with("name", name))
            .retrieve()
            .bodyToMono(ImgbbUploadResponse.class)
            .map(ImgbbUploadResponse::getDisplayUrl)
            .onErrorMap(WebClientResponseException.GatewayTimeout.class, ex ->
                new CommonException(ResponseCode.EXTERNAL_API_TIMEOUT))
            .block();

        return response;
    }
}


@Data
public class ImgbbUploadResponse {

    private JsonData data;

    @Data
    public static class JsonData {

        @JsonProperty("display_url")
        private String displayUrl;
    }

    public String getDisplayUrl() {
        return data.getDisplayUrl();
    }
}

 

ImgUploadTemplate을 만들어서 사용했다.

uploadImage 메소드를 통해 받은 이미지 파일과 이름을 가지고 요청을 보내고, 그 결과 중에서 displayUrl을 가져오도록 ImgbbUploadResponse 클래스를 사용했다. 

 

 

5. 유의할 점

이미지 호스팅을 ImgBB에 너무 의존하다보니 해당 Api에 문제가 생길 경우 이미지 업로드에 문제가 생긴다.

실제로 api timeout 이 프로젝트 중 종종 발생했다.

그래서 일단 해당 예외를 던지게 위에서 써 놓긴 했는데 이는 추후에 좀 더 수정할 필요가 있어 보인다. api timeout 오류가 될 때까지 시간이 좀 걸리는지라... 

다음에 수정하지 뭐! 희희

 

 

 

근데 확실히 이걸 써보니까 느꼈다.

공부 좀 해라