Search code examples
javarestapache-httpclient-4.xhttp-deleteviewparams

How to send Entity in API DELETE with HTTP-CLIENT


I have to call a DELETE Method inside one of the APIS of a client. This shouldn´t be a problem but I am struggling with the framework that my company currently uses and I hope I can get some info that hopefully will help me solve the problem:

First thing first.

1: The api doesn´t work if I do the call sending the params as URL: enter image description here

2: It works completely OK if I send the params inside the body as x-www-form-urlencoded but not form-data or raw enter image description here

The documentation of the method inside the API told us the following: (Important to Look to IDEtapa)

enter image description here

I have to do this call in JAVA (JAVA 8) currently my company uses HTTP_CLIENT as the main framework for APICalls.

My code: The build of the Data (Currently I build both, as Entity and as Params for you to view I´ve tried with each one of them indepently):

Map datosApi = new HashMap<>(); datosApi.put(Constants.URL, anular_cita);

    Map headers = new HashMap<>();
    headers.put(Constants.AUTHORIZATION, params.get("token_autorizacion"));
    headers.put("Content-Type", "application/json");
    headers.put("entity_charset", "UTF-8");

    datosApi.put(Constants.HEADERS, headers);
    JSONObject entity = new JSONObject();
    Map param = new HashMap();
    param.put(Constants.ID_CENTRO, consul);
    param.put("IdAsistencia", propiedades[0]);
    param.put("IdCapitulo", propiedades[1]);
    param.put("IdEtapa", Integer.valueOf(propiedades[2]));
    entity.put(Constants.ID_CENTRO, consul);
    entity.put("IdAsistencia", propiedades[0]);
    entity.put("IdCapitulo", propiedades[1]);
    entity.put("IdEtapa", Integer.valueOf(propiedades[2]));
    datosApi.put("entity", entity.toString());
    datosApi.put("entity_mime_type", "application/json");
    datosApi.put("entity_charset", "UTF-8");

    datosApi.put("params", param);
    String anularCita = APIDao.callAPIDelete(datosApi);

The preparation for my call to the framework:

         public static String callAPIDelete(Map in) {
            String contentString = "";
            Map res = new HashMap<>();
            try {
                res = XWM.execute("delete@http_client", in);
                byte[] content = (byte[]) res.get("content");
                contentString = new String(content, StandardCharsets.UTF_8);
        
   
 

And inside our framework we have this:

if (StringUtils.equals(StringUtils.trim(method), "delete"))
                        {
                            StringBuilder requestUrl = new StringBuilder(url);
                            if (formparams != null)
                            {
                                if (requestUrl.indexOf("?")==-1)    requestUrl.append("?");
                                else                                requestUrl.append("&");
                                requestUrl.append(URLEncodedUtils.format(formparams, charset));
                        }
                        
                        if (entityRequest != null)
                        {
                            log.error("Param 'entity' no puede usarse en get (se ignora)");
                        }

                        HttpDelete delete = new HttpDelete(requestUrl.toString());  
                        delete.setConfig(requestConfig);            
                        uriRequest = delete;   
                    }
                }
            }
        }
        
        // Headers
        if (headers != null)
        {
            for (String h: headers.keySet()) uriRequest.addHeader(h, headers.get(h));
        }
        
        // Ejecutamos método
        log.info("Executing request " + uriRequest.getRequestLine());
        CloseableHttpResponse response = null;
        
        if (!preemtiveAuth || credsProvider == null)
        {
            response = httpclient.execute(uriRequest);
        }

As you can see, in the delete method, we ignore the entity that i´ve built in the first patch of code. The HTTPDelete Class is APACHE, the url with info of the class is the following: https://www.javadoc.io/doc/org.apache.httpcomponents/httpclient/4.5.2/org/apache/http/client/methods/HttpDelete.html

The question can be divided in two:

1: Can we send the Entity in a Delete Call? I have found a few info about this in the following places:

Is an entity body allowed for an HTTP DELETE request?

https://web.archive.org/web/20090213142728/http://msdn.microsoft.com:80/en-us/library/cc716657.aspx

https://peterdaugaardrasmussen.com/2020/11/14/rest-should-you-use-a-body-for-your-http-delete-requests/

I assume that in order to do it, i would need a new HttpDelete that would allow us to use entity, if possible, could you give me some examples of this?

2: For what i understand of the links i posted above, while using entity in Delete calls is not forbidden is something that is not encouraged, Should I just talk with the people who made the API and ask them to change their configuration to allow us to send the info by params? (It is not personal or sensible info, just a bunch of IDs)

Thank you so much for your attention and my apologies for any typo or format mistake, still learning how to make good posts.

EDIT: i have found this answer setEntity in HttpDelete that more or less solve the first issue about if its, posible to send an Entity in a Delete call, but still, don´t now if it should be better to ask them to change their method


Solution

  • As told in the coments by Ewramner and VoiceOfUnreason and in the edits:

    1: The answer about how to make this was found in an older post of StackOverflow: setEntity in HttpDelete

    2: The answer about "Should I just talk with the people who made the API and ask them to change their configuration to allow us to send the info by params?" was answered by both of them. While it´s not forbidden, it´s something thats not recommended.

    My course of action will be:

    1: Talk with the people responsible for the API to give them info about this situation.

    2: Ask our Architecture team to create a new method that will allow us to do HttpDelete calls with an entity body, just in case that we have to make more API calls like this one.

    With this i think all my answers are solved.

    Again, Thank you.