Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle bulk Item updates in single API Request - PUT #100

Open
mfoolio opened this issue Feb 3, 2023 · 1 comment
Open

Handle bulk Item updates in single API Request - PUT #100

mfoolio opened this issue Feb 3, 2023 · 1 comment

Comments

@mfoolio
Copy link

mfoolio commented Feb 3, 2023

Attempting to update multiple ZohoBooks "Item" records with the "update" method quickly leads to API rate limits.

Using a PUT to the bare "/items" with a JSON object of many Item records will update them all with a single API call. The reply data is a JSON array with single top-level array of "items" with each record being the full updated individual Item and also the response "Code" and "Message" that would normally be returned from a single Item's update/PUT call.

While this ZohoBooksApi module allows to send an update to the bare "/items" by providing "null" as the id to the ->update() method (which in turns sends it to ->put()), the current release does not properly handle the resulting data response from the Zoho API.

Two issues presented:

  • Client.php - processResult() function does not have a case to handle a valid JSON response without a "Code" and "Message" at the top level, and
  • Module.php - update() function is only set up to handle and return a single Model Item from make()

To resolve for immediate use I modified code as follows:

  • processResult() in Client.php to accept the case where the data returned is a JSON object but does not have a top-level "Code" field.
        if (!$result) {
            // All ok, probably not json, like PDF?
            if ($response->getStatusCode() >= 200 && $response->getStatusCode() <= 299) {
                return (string)$response->getBody();
            }

            throw new ErrorResponseException($response->getReasonPhrase(), $response->getStatusCode());
        }

        if (isset($result['code']))
        {
            if ($result['code'] != 0)
            {
                throw new ErrorResponseException('Response from Zoho is not success. Message: ' . $result['message'], $result['code'] ?? $response->getStatusCode());
            } else
            {
                // All OK
                return $result;
            }
        }

        // All OK, JSON and likely bulk update with individual response codes
        return $result;
    }
  • update() in Module.php to test for a "null" $id, and if so to just return the decoded JSON array.
    public function update($id, $data, $params = [])
    {
        $data = $this->client->put($this->getUrl(), $id, $data, $params);

        if ($id != null)
        {
            // Updated single object
            $data = $data[$this->inflector->singularize($this->getResourceItemKey())];
            return $this->make($data);
        } else
        {
            // Updated muliple objects, return collection
            // case for bulk ie. update PUT to /items

            // body is top level of module name i.e. 'items'
            // array of each object that was submitted, 'code' and 'message' is in each sub object

            return $data[$this->getResourceKey()];
        }
    }

Would it be more desirable to create another Module method such as updateMany() instead of passing in a null id?
Are there consequences or other cases where processResult() shouldn't just return the JSON data object?

@Skullbock
Copy link
Contributor

We deal with this in our CRM module, so if you feel like it you can check that implementation (https://github.com/Weble/ZohoCRMApi and let me know if that make sense in this use case, and we'll accept a PR for this gladly :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants