Search code examples
flutterflutter-getx

GetConnect Post API calls not working in Flutter Web says : 415 Unsupported Media Type


I am using GetConnect for API call in my Flutter project.

getx version : 4.6.6
Flutter version : 3.16

Here is the API call function:

class ApiProvider extends GetConnect {

    @override
    void onInit() {
        httpClient.baseUrl = BASE_URL;
        httpClient.defaultContentType = "application/json";
        httpClient.maxAuthRetries = 3;
        httpClient.timeout = Duration(seconds: 600);
    }

    Future<Response> loginUserApi(LoginRequest data) =>
      post("v1/user/signIn", json.encode(data.toJson()),
          contentType: "application/json" , headers: {
            'Content-Type': 'application/json',
            'Accept': '*/*',
            'App-ID': 'CUSTOMER',
          } );
        }

This function is working fine on Android and iOS devices, but when I run my project on Flutter Web, it says:

[GETX] Cannot decode server response to json

And in network tab of Chrome it says:

Status Code : 415 Unsupported Media Type

When I call same API using dio it's working on Flutter Web and other platforms.

enter image description here


Solution

  • After inspecting Flutter web in Chrome, I noticed that when I set 'Content-Type': 'application/json', it results in the Content-Type being set twice. This I noticed in inspect window's network tab, where the Content-Type shows as "application/json application/json" within the request headers, refer to screenshot below:

    enter image description here

    This issue led to the server responding with a 415 Unsupported Media Type error. It appears that on Flutter web, httpClient.defaultContentType = "application/json"; works, so there is no need to set content type again. However, on mobile, we must explicitly set the content type within our headers. As a solution, I modified my provider as follows:

    class BffApiProvider extends GetConnect {
      @override
      void onInit() {
        httpClient.baseUrl = BFF_BASE_URL;
        httpClient.defaultContentType = "application/json";
        httpClient.maxAuthRetries = 3;
        httpClient.timeout = Duration(seconds: 600);
    
        var headers;
        if (kIsWeb) {
          headers = {
            'Accept': 'application/json',
          };
        } else {
          headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
          };
        }
    
        // for login
        Future<Response> loginUserApi(LoginRequest data) =>
            post("user/signIn", json.encode(data.toJson()));
      }
    }
    

    Now, all POST API calls work correctly on both mobile and Flutter web. I hope this solution helps someone using GetConnect for API calls in Flutter. Happy coding!