programing

REST API - 파일(이미지) 처리 - 베스트 프랙티스

skycolor 2023. 3. 18. 08:26
반응형

REST API - 파일(이미지) 처리 - 베스트 프랙티스

JSON을 받아들여 응답하는 REST API로 서버를 개발하고 있습니다.문제는 클라이언트에서 서버로 이미지를 업로드해야 하는지 여부입니다.

주의: 또한 엔티티(사용자)가 여러 파일(carPhoto, licensePhoto)을 가질 수 있고 다른 속성(이름, 이메일...)도 가질 수 있는 사용 사례에 대해 설명하겠습니다.단, 새로운 사용자를 생성하면 이러한 이미지는 등록 프로세스 후에 추가되지 않습니다.


내가 알고 있는 솔루션, 그러나 각각의 솔루션에는 몇 가지 결함이 있다.

1. JSON 대신 Multipart/Form Data 사용

good : POST 및 PUT 요청은 가능한 한 RESTful이며 텍스트 입력과 파일을 포함할 수 있습니다.

단점 : JSON이 아니므로 멀티파트/폼데이터에 비해 테스트, 디버깅 등이 훨씬 용이합니다.

2. 개별 파일 업데이트 허용

새로운 사용자 생성에 대한 POST 요청은 이미지 추가를 허용하지 않습니다(처음 말한 사용 예에서는 괜찮지만). PUT 요청에 의해 멀티파트/폼 데이터로서 /users/4/carPhoto에 업로드됩니다.

good : 파일업로드 자체를 제외한 모든 것이 JSON에 남습니다.테스트와 디버깅이 간단합니다(길이에 구애받지 않고 완전한 JSON 요구를 기록할 수 있습니다).

단점 : 직관적이지 않습니다.엔티티의 모든 변수를 동시에 POST 또는 PUT할 수 없습니다.또, 이 주소도 마찬가지입니다./users/4/carPhoto할 수 의 표준 )./users/4/shipmentsusers/4/name )를를를를를를를를를 ( users / 4 / name ) get GET / PUT 할)다다다usersusersusersusersusersusersusersusersusersusersusersusersusersusersusersusers 。하여 이름을 /4users/4의 GET에서 을 변경할 수 .아이디 users/4/reviews 。

3. Base64 사용

JSON으로 전송하지만 Base64로 파일을 인코딩합니다.

good : 첫 번째 솔루션과 마찬가지로 가능한 한 RESTful 서비스입니다.

단점 : 다시 말씀드리지만 테스트와 디버깅은 훨씬 더 심합니다(본문에는 메가바이트의 데이터가 있을 수 있습니다).클라이언트와 서버 양쪽에서 크기와 처리 시간이 증가합니다.


솔루션 2번을 꼭 사용하고 싶은데 단점이 있어서..."최적의" 솔루션에 대한 더 나은 통찰력을 얻을 수 있는 사람은 누구입니까?

가능한 한 많은 표준이 포함된 RESTful 서비스를 제공하는 것이 목표이며, 가능한 한 심플하게 유지하고 싶습니다.

여기서 OP (2년 만에 이 질문에 대답합니다.Daniel Cerecedo의 투고는 한때 나쁘지 않았지만 웹 서비스는 매우 빠르게 발전하고 있습니다.)

3년간의 풀타임 소프트웨어 개발(소프트웨어 아키텍처, 프로젝트 관리 및 마이크로 서비스 아키텍처에도 중점을 두고)을 통해 두 번째 방법(단, 1개의 일반 엔드포인트 포함)을 최선의 방법으로 선택했습니다.

이미지에 대해 특별한 엔드포인트가 있는 경우 이러한 이미지를 처리하는 데 훨씬 더 많은 권한을 부여합니다.

모바일 앱(iOS/안드로이드)과 프런트엔드(React 사용) 모두 동일한 REST API(Node.js)를 보유하고 있습니다.지금은 2017년이므로 이미지를 로컬에 저장하지 않고 클라우드 스토리지(Google 클라우드, s3, 클라우드 바이너리 등)에 업로드해야 하므로 일반적인 처리가 필요합니다.

일반적인 흐름은 이미지를 선택하면 백그라운드에서 업로드가 시작되고(일반적으로 /images 엔드포인트에서 POST), 업로드 후 ID가 반환됩니다.사용자가 이미지를 선택한 후 일반적으로 다른 필드(주소, 이름 등)로 진행되기 때문에 사용자가 "보내기" 버튼을 누르면 이미지가 이미 업로드되어 있습니다.그는 업로드 중이라는 화면을 기다리지 않고 지켜본다..".

이미지 취득도 마찬가지입니다.특히 휴대폰과 제한된 모바일 데이터 덕분에 원본 이미지를 전송하지 않고 크기가 조정된 이미지를 전송하고 싶기 때문에 대역폭이 많이 필요하지 않습니다(또한 모바일 앱의 크기를 전혀 조정하지 않고 사용자의 보기에 딱 맞는 이미지를 원합니다).이러한 이유로 좋은 앱은 클라우드 바이너리(또는 크기 조정을 위한 자체 이미지 서버)와 같은 것을 사용하고 있습니다.

또한 데이터가 비공개 데이터가 아닌 경우 앱/프런트엔드에 URL만 전송하면 클라우드 스토리지에서 직접 다운로드되므로 서버의 대역폭과 처리 시간이 크게 절약됩니다.대규모 애플리케이션에서는 매달 많은 테라바이트가 다운로드됩니다. CRUD 운영에 중점을 둔 각 REST API 서버에서 직접 이 작업을 처리하고 싶지 않습니다.한 곳에서 처리하거나(캐시 기능이 있는 Images Server 등) 클라우드 서비스가 모든 것을 처리하도록 해야 합니다.


단점 : 단점이라고 생각할 수 있는 것은 "할당되지 않은 이미지"뿐입니다.사용자가 이미지를 선택하고 다른 필드를 계속 채우지만, 그는 "아니오"라고 말하고 앱이나 탭을 끄지만, 당신은 이미지를 성공적으로 업로드했습니다.즉, 할당되어 있지 않은 이미지가 업로드 되어 있는 것을 의미합니다.

이 문제를 해결하는 방법에는 여러 가지가 있습니다.가장 쉬운 방법은 "I don't care (상관없습니다)"입니다.이것이 자주 일어나지 않거나 사용자가 보내는 모든 이미지를 저장하려는 경우(어떤 이유로든) 삭제하지 않을 수 있습니다.

또 다른 방법은 간단합니다.즉, 매주 CRON을 사용하고 1주일보다 오래된 미지정 이미지를 모두 삭제합니다.

가지 결정을 내려야 합니다.

  1. 리소스 경로에 대한 첫 번째:

    • 이미지를 리소스로 모델링합니다.

      • Nested in user(/user/:id/image): 사용자와 이미지 간의 관계는 암묵적으로 이루어집니다.

      • 루트 경로(/image):

        • 고객은 이미지와 사용자 간의 관계를 확립할 책임이 있습니다.

        • 이미지 작성에 사용되는 POST 요구와 함께 보안 컨텍스트가 제공되는 경우 서버는 인증된 사용자와 이미지 간의 관계를 암묵적으로 확립할 수 있습니다.

    • 사용자의 일부로 이미지 삽입

  2. 두 번째 결정은 이미지 리소스를 표시하는 방법에 관한 것입니다.

    • Base 64 인코딩된 JSON 페이로드로서
    • 멀티파트 페이로드로서

이것이 나의 의사결정 트랙이 될 것이다.

  • 저는 성능보다 디자인을 더 선호합니다. 단, 강력한 이유가 없는 한 말이죠.이를 통해 시스템의 유지보수가 용이해지고 통합업체가 보다 쉽게 이해할 수 있습니다.
  • 우선 이미지 리소스를 Base64로 표현하면 모든 JSON을 유지할 수 있습니다.이 옵션을 선택한 경우 리소스 경로를 원하는 대로 모델링할 수 있습니다.
    • 사용자와 이미지의 관계가 1 대 1인 경우, 특히 두 데이터 세트가 동시에 업데이트되는 경우 속성으로 이미지를 모델링하는 것이 좋습니다.그 외의 경우, 이미지를 속성으로 모델화하거나 PUT 또는 PATCH를 통해 업데이트하거나 별도의 리소스로 모델화할 수 있습니다.
  • 멀티파트 payload를 선택하면 이미지에 대해 바이너리 표현을 사용하는 결정에 영향을 받지 않도록 이미지를 자체 리소스로 모델링해야 합니다.

그러면 다음과 같은 질문이 나옵니다.base64와 multipart를 선택하면 퍼포먼스에 영향이 있습니까?멀티파트 형식으로 데이터를 교환하는 것이 더 효율적이라고 생각할 수 있습니다.그러나 이 기사는 두 표현 모두 크기 면에서 얼마나 큰 차이가 없는지를 보여준다.

나의 선택 Base64:

  • 일관된 설계 결정
  • 퍼포먼스에 미치는 영향은 미미하다
  • 브라우저는 데이터 URI(base64 부호화 이미지)를 인식하므로 클라이언트가 브라우저일 경우 이러한 URI를 변환할 필요가 없습니다.
  • 속성으로 할지 독립형 리소스로 할지 여부에 대해서는 투표하지 않습니다.문제 영역(모르겠습니다)과 개인 취향에 따라 달라집니다.

두 번째 솔루션이 가장 정확할 것입니다. 및 하여 HTTP mimtype을 통해 .multipart/form-data관계를 다루는 한, 저는 이 프로세스를 사용합니다(고객의 전제 조건이나 시스템 설계에 대해서는 전혀 모릅니다).

  1. POST로로 합니다./users사용자 엔티티를 만듭니다.
  2. POST를 「 」로 설정합니다./imagesLocationHTTP " " " " " " " 입니다.
  3. PATCH로로 합니다./users/carPhoto 아이디 '아이디'에.Locationheader를 지정합니다.

쉬운 해결책은 없다., 표준적인 은 첫 선택지, 즉 '일단'을 하는 것입니다.multipart/form-dataW3 권장 가이드에서 말하는 바와 같이

파일, ASCII가 아닌 데이터 및 이진 데이터를 포함하는 양식을 제출하려면 컨텐츠 유형 "multipart/form-data"를 사용해야 합니다.

실제로 양식을 보내진 않았지만 암묵적인 원칙은 여전히 적용되죠base64를 바이너리 표현으로 사용하는 것은 잘못된 툴을 사용하여 목표를 달성하고 있기 때문에 올바르지 않습니다.다른 한편, 두 번째 옵션은 API 서비스를 소비하기 위해 API 클라이언트가 더 많은 작업을 수행하도록 강요합니다.소비하기 쉬운 API를 제공하기 위해서는 서버측에서 어려운 작업을 해야 합니다.첫 번째 옵션은 디버깅이 쉽지 않지만 디버깅을 실행해도 변경되지 않을 수 있습니다.

사용.multipart/form-data당신은 REST/HTTP 철학을 고수하고 있습니다.여기에서 유사한 질문에 대한 답변을 볼 수 있습니다.

다른 옵션을 혼재시킬 경우 멀티파트/폼데이터를 사용할 수 있지만 모든 값을 개별적으로 전송하는 대신 payload라는 이름의 값을 json payload와 함께 전송할 수 있습니다(ASP를 사용하여 이 방법을 시도했습니다).NET WebAPI 2로 정상적으로 동작합니다).

언급URL : https://stackoverflow.com/questions/33279153/rest-api-file-ie-images-processing-best-practices

반응형