5

I am using Nodejs to connect with GoogleApis v35.0.0 to tell Google to update or remove pages from the Google index. And I stuck in the multipart/mixed request, the body of multipart when I send the request through Google indexing batch request.

I could able to send an individual page update request to Google by following the indexing API documentation. But since Google has the limited quota at maximum of 200 requests per day and I need to update more URL's than that. So, I am trying to use google indexing batch request which can group at maximum of 100 individual requests and it counts as 1 request.

I am having issue with the correct format of multipart body when I am trying to send the request by batch. I am using JWT (JSON Web Token) of GoogleApis which extended from oauth2 to authenticate my account and using the request library v2.88.0 to send the request to Google.

Since request library already handle the multipart boundary that's why I am not sending that as one of the request options information. I also check the information in the multipart/mixed of the request npm library but I only found the one similar but not the same which is the multipart/related (https://github.com/request/request#multipartrelated).

According to the piece of batch request body example from Google, I need to use multipart/mixed as content type in the main request:

POST /batch HTTP/1.1
Host: indexing.googleapis.com
Content-Length: content_length
Content-Type: multipart/mixed; boundary="===============7330845974216740156=="
Authorization: Bearer oauth2_token

--===============7330845974216740156==
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: <b29c5de2-0db4-490b-b421-6a51b598bd22+2>

POST /v3/urlNotifications:publish [1]
Content-Type: application/json
accept: application/json
content-length: 58

{ "url": "http://example.com/jobs/42", "type": "URL_UPDATED" }

Here's my code:

    return jwtClient.authorize(function(err, tokens) {
      if (err) {
        console.log(err);
        return;
      }

      let options = {
        url: 'https://indexing.googleapis.com/batch',
        method: 'POST',
        headers: {
          'Content-Type': 'multipart/mixed'
        },
        auth: { 'bearer': tokens.access_token },
        multipart: [
          {
            body: JSON.stringify({
              headers: {
                'Content-Type': 'application/http'
              },
              method: 'POST',
              url: 'https://indexing.googleapis.com/v3/urlNotifications:publish',
              body: {
                'Content-Type': 'application/json',
                url: 'https://www.test.com/es/1234',
                type: 'URL_UPDATED'
              }
            })
          }
        ]
      };

      request(options, function (error, response, body) {
        console.log(body);
      });

    });

I am getting error in the body of multipart, I don't know which kind of body google indexing batch request is waiting for. Seems like everything inside the body of multipart are considering as headers. But according to the documentation the format of batch request, it says that "Each part begins with its own Content-Type: application/http HTTP header. The body of each part is itself a complete HTTP request, with its own verb, URL, headers, and body". For more details information check: https://cloud.google.com/storage/docs/json_api/v1/how-tos/batch.

However, I am getting the following error when I execute my code:

{
  "error": {
    "code": 400,
    "message": "Failed to parse batch request, error: Failed in parsing HTTP headers: {\"Content-Type\":\"application/http\",\"method\":\"POST\",\"url\":\"https://indexing.googleapis.com/v3/urlNotifications:publish\",\"body\":{\"Content-Type\":\"application/json\",\"url\":\"https://www.test.com/es/1234\",\"type\":\"URL_UPDATED\"}}\n. Received batch body: ",
    "status": "INVALID_ARGUMENT"
  }
}

Does someone know which is the correct format of body inside the multipart when it request to google indexing batch request?

Thanks in the advance!

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
Jing
  • 145
  • 1
  • 9

2 Answers2

4

Batching does not help avoid quota limits

I could able to send an individual page update request to Google by following the indexing API documentation. But since Google has the limited quota at maximum of 200 requests per day and I need to update more URL's than that. So, I am trying to use google indexing batch request which can group at maximum of 100 individual requests and it counts as 1 request.

There is nothing in batching that states it only counts as one against your quota.

While batching can save you on the overhead of constructing many HTTP requests each Google APIs request within a batch request will count against your daily project quota. By default a project can make up to 200 request per day; batching will not help you stay below this quota.

Apply for a higher quota

Have you considered applying for a higher quota? I know it can take time to get the response back, but you may just want to wait and see what they say.

enter image description here

Note google-apis-nodejs-client

The library does not support batching so you are going to have to do it yourself as you are currently #1130

Your Actual issue

Let me know if you want to continue trying to get batching working. I will see if i can help. With manual version.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • Thanks @daimto. (I'm involved in the same project as @jing). Two follow-ups: (1) Correct, our objective with batching was to be able to surpass the default quota. (2) We began developing the batched requests because we reached a dead-end with the quota limit increase (we submitted a request for an increase through the process you indicate in your answer on Dec 17, 2018). If you know how to give a push for the team at Google to review our request approved, we'd greatly appreciate it (and likely save us a bunch of hassle! ;-) – Paulo Jan 25 '19 at 14:42
  • Thanks @daimto for answering and clarifying. We'd definitely appreciate if you could help us with what Paulo aforementioned. Last thing, I would appreciate if you could give me advice to solve my current issue just for personal goal. – Jing Jan 25 '19 at 15:22
  • Have you tried to go over 200 since you applied? I don't have any contacts on that team unfortunately. It can take months to be approved and sometimes you just get approved without being notified you just need to try. – Linda Lawton - DaImTo Jan 26 '19 at 07:55
  • Yes I tried, and get an error once it goes over 200 :( We will wait for Google to get the approval. According to my current issue with the manual version, do you know why I am getting the INVALID_ARGUMENT with the multipart/mixed request? Thanks @DaImTo! – Jing Jan 31 '19 at 16:29
  • I have never tried to get batching working manually i have always used one of the libraries that supports it. – Linda Lawton - DaImTo Jan 31 '19 at 18:16
  • 1
    Okay, thanks @DaImTo! We just got the limit request approved today from Google. – Jing Feb 01 '19 at 11:55
  • I am glad i could help please remember to accept the anwser if it helped you – Linda Lawton - DaImTo Feb 06 '19 at 13:56
4

As @DalmTo says the quota will still apply, even to batch requests. But also you are not correctly constructing the payload, the following example works.

const items = batch
  .filter(x => x)
  .map(line => {
    return {
      'Content-Type': 'application/http',
      'Content-ID': batchId,
      body:
        'POST /v3/urlNotifications:publish HTTP/1.1\n' +
        'Content-Type: application/json\n\n' +
        JSON.stringify({
          url: line,
          type: 'URL_UPDATED',
        }),
    };
  });
const options = {
  url: 'https://indexing.googleapis.com/batch',
  method: 'POST',
  headers: {
    'Content-Type': 'multipart/mixed',
  },
  auth: { bearer: access_token },
  multipart: items,
};
request(options, (err, resp, body) => {
  //...
});
David
  • 8,340
  • 7
  • 49
  • 71