7 Replies Latest reply: Aug 27, 2018 9:12 AM by Joshua Pierlo RSS

    Rest API Deleting Sheets

    Joshua Pierlo

      Hi!

       

      I've been working on a function that duplicates an app with a selection of sheets.

      The way I do this is by simply duplicating the app, and going trough a list of sheets that have not been selected to make sure these sheets get deleted in the duplicated app.

       

      I've tried using the following endpoints:

       

      await _qrsClient.Delete("qrs/app/appcontent/"+ newAppSheet.ID +"/delete?xrfkey=(key)","");

      await _qrsClient.Delete("/qrs/appcontent/newAppID/deletecontentexternalpath="+newAppSheet.Name+"&xrfkey=(key)");

      await _qrsClient.Delete("qrs/appcontent/"+ newAppID +"/deleteexternalpath="+newAppSheet.Name+"&xrfkey=(key)");

      await _qrsClient.Delete("qrs/appobject/(SheetIDOfSheetThatNeedsToBeDeleted)/delete?xrfkey=(key)");

       

      Sadly to no avail as it keeps giving me "http request header is incorrect" on the first 2 request and "Object reference not set to an instance of an object" on the third & fourth.

       

      I've also tracked the network activity on deleting sheets trough the QMC using the following endpoints:
      await _qrsClient.Delete("qrs/selection/(sheetid)/app/object?xrfkey=(key)");

      await _qrsClient.Delete("qrs/selection/(sheetid)?xrfkey=(key)");

      but also to no avail.... (the http request header is incorrect).

      https://help.qlik.com/en-US/sense-developer/June2018/apis/repositoryserviceapi/index.html#0bd3d491Ba7d3e55008fA7d80628fd…

       

       

      I've looked trough the rest API endpoint documentation but I can't find any examples on how to actually delete a sheet trough rest API. Does anyone have a clue?

        • Re: Rest API Deleting Sheets
          Erik Wetterberg

          Hi,

          You need to include the xrfkey both as a URL parameter and as a http header.

           

          Erik Wetterberg

          https://extendingqlik.upper88.com/

            • Re: Rest API Deleting Sheets
              Joshua Pierlo

              Hi Erik,

               

              Thank you for your response.

              The HTTP header is set in a different class that describes the _qrsClient.

              I have taken a screenshot of the delete-class.

               

              9e5abaae066f18ee6332742b5ff7fcf5.png

                • Re: Rest API Deleting Sheets
                  Erik Wetterberg

                  How do you make sure the same xrfkey is used?

                   

                  Erik Wetterberg

                    • Re: Rest API Deleting Sheets
                      Joshua Pierlo

                      Hi Erik, thanks for your response

                       

                      It's only used a couple of times troughout the whole application, and it's predefined.

                      I double checked and I'm 100% positive that they're the same.

                       

                      Also i'm using this delete task.

                       

                      public async Task<string> Delete(string endpoint)

                              {

                                  SetHeaders(_client);

                                  _client.QueryString = _queryStringCollection;

                                  try

                                  {

                                      while (_client.IsBusy)

                                      {

                                          await Task.Delay(200);

                                      }

                                      return await _client.UploadStringTaskAsync(_serverURL + endpoint, "Delete", "").ConfigureAwait(false);

                                  }

                                  catch (WebException ex)

                                  {

                                      throw new Exception(await ParseWebException(ex).ConfigureAwait(false), ex);

                                  }

                              }

                       

                      -the SetHeaders takes care of adding the headers (including the xrfkey aswell),

                      -the server URL is our qliksense server (https://OurIP)

                      -the endpoint is /qrs/selection/{SHEET-ID}/app/object?xrfkey as shown in the screenshot above.

                       

                      The exception thrown in the catch is:

                      "The remote server returned an error: (400) Bad Request."

                       

                      Also, I've checked the networking activities when deleting a sheet trough the QMC and it included the port aswell (433).

                      I tried adding it to the endpoint (:433/qrs/selection/{SHEET-ID}/app/object?xrfkey) but it gives me an Unable to connect to the remote server. Checked the port listings and the proxy service is running on port 433 as usual....

                        • Re: Rest API Deleting Sheets
                          Erik Wetterberg

                          Hi,

                          Are you sure about the endpoint? I would expect it to be something like '/qrs/[type]/{id}' as described here. The type would be 'app/object' in your case. Delete app object is not described in the documentation, but compare to the URL described for publish.

                           

                          Erik Wetterberg

                          https://extendingqlik.upper88.com/

                            • Re: Rest API Deleting Sheets
                              Joshua Pierlo

                              I have found the error.

                              The method is actually working fine, just the provided ID does not match the ID that should be sent.

                               

                              After contact with the Qlik Support team we have made it work by re-writing the whole sheetID receiving process.

                              This is quoted directly from Qlik Support if anyone has the same problem:

                               

                              1) Get the object (sheet) id via GET /qrs/app/object?xrfkey=somerandomstring&filter=app.name eq 'SomeApp' and objectType eq 'sheet' and name eq 'deleteMe'. Example response:

                              (returns 200 OK with json body below)

                              [

                              {

                              "id": "592184be-8691-4d89-9377-5859abab4486",

                              "engineObjectType": "",

                              "description": "",

                              "objectType": "sheet",

                              "publishTime": "1753-01-01T00:00:00.000Z",

                              "published": false,

                              "name": "deleteMe",

                              "engineObjectId": "b0cc25a5-2fc7-4c7c-934c-b1466770c8ee",

                              "contentHash": "IM4*K[9PGEY)QUGC'<Q\\A\"D^K#2CF0V\\K-#[:L9Y>OW",

                              "privileges": null

                              }

                              ]

                               

                              2) Delete via DELETE /qrs/app/object/592184be-8691-4d89-9377-5859abab4486?xrfkey=somerandomstring

                              (returns 204 No Content if successful)