WHOATEMYNOODLES
WHOATEMYNOODLES

Reputation: 2731

Retrofit - @Part MultipartBody.Part is not triggering API

Retrofit call works fine with my API, for example:

@POST("addeventphoto")
Call<NewPhotoObject> listRepos(@Query("key1") String testKey);
RetrofitInterfaces.IPostNewMessage service = RetrofitClientInstance.getRetrofitInstance().create(RetrofitInterfaces.IPostNewMessage.class);
        Call<NewPhotoObject> call = service.listRepos("hello");
        call.enqueue(new Callback<NewPhotoObject>() {
            @Override
            public void onResponse(Call<NewPhotoObject> call, Response<NewPhotoObject> response) {
                Log.d(TAG, "onResponse: " + response.body());
                if(response.isSuccessful() && response.body() != null){
                    Log.d(TAG, "onResponse: " + response.body().getEvent_photo());
                }

            }

            @Override
            public void onFailure(Call<NewPhotoObject> call, Throwable t) {
                Log.d(TAG, "onFailure: " + t);
            }
        });

My API is triggered and I get a response back. However as soon as I add @Multipart to my Retrofit interface... my API is no longer being triggered.

@Multipart
@POST("addeventphoto")
Call<NewPhotoObject> listRepos(@Query("key1") String testKey, @Part MultipartBody.Part image);

Am I using retrofit incorrectly? Currently version:

implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

Edit: Using with MultipartBody.Part

File file = new File(imagePath);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);

RetrofitInterfaces.IPostNewMessage service = RetrofitClientInstance.getRetrofitInstance().create(RetrofitInterfaces.IPostNewMessage.class);
        Call<NewPhotoObject> call = service.listRepos("hello", body);
        call.enqueue(new Callback<NewPhotoObject>() {
            @Override
            public void onResponse(Call<NewPhotoObject> call, Response<NewPhotoObject> response) {
                Log.d(TAG, "onResponse: " + response.body());
                if(response.isSuccessful() && response.body() != null){
                    Log.d(TAG, "onResponse: " + response.body().getEvent_photo());
                }

            }

            @Override
            public void onFailure(Call<NewPhotoObject> call, Throwable t) {
                Log.d(TAG, "onFailure: " + t);
            }
        });

Upvotes: 0

Views: 184

Answers (2)

WHOATEMYNOODLES
WHOATEMYNOODLES

Reputation: 2731

I was using API Gateway + Lambda and you need to manually enable Binary Support in order to accept MultipartBody.Part type. Thats why it was successfully sent, but my API was not being fired.

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-configure-with-console.html

Upvotes: 1

Eldhopj
Eldhopj

Reputation: 3579

You need scalar converter factory in order to pass the value in multipart

add this dependency

implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version"

And in your retrofit client class add converter factory

.addConverterFactory(ScalarsConverterFactory.create())

Sample code is given below

retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(ScalarsConverterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .client(httpClient.build())
        .build();

Upvotes: 0

Related Questions