Pobieranie określonych wersji zasobów

Każdy zasób ma pole wersji, które zmienia się za każdym razem, gdy zasób ulega zmianie – pole etag. Tagi ETag są standardową częścią protokołu HTTP i są obsługiwane w interfejsie Calendar API w 2 przypadkach:

  • przy modyfikacjach zasobów, aby mieć pewność, że w międzyczasie nie nastąpił żaden inny zapis w tym zasobie (modyfikacja warunkowa);
  • przy pobieraniu zasobów, aby pobierać dane zasobów tylko wtedy, gdy zasób uległ zmianie (pobieranie warunkowe).

Modyfikacja warunkowa

Jeśli chcesz zaktualizować lub usunąć zasób tylko wtedy, gdy nie został on zmieniony od czasu ostatniego pobrania, możesz określić nagłówek If-Match, który zawiera wartość tagu ETag z poprzedniego pobrania. Jest to bardzo przydatne, aby zapobiec utracie modyfikacji zasobów. Klienci mają możliwość ponownego pobrania zasobu i ponownego zastosowania zmian.

Jeśli wpis (i jego tag ETag) nie uległ zmianie od czasu ostatniego pobrania, modyfikacja się powiedzie i zostanie zwrócona nowa wersja zasobu z nowym tagiem ETag. W przeciwnym razie otrzymasz kod odpowiedzi 412 (Precondition failed).

Poniższy fragment przykładowego kodu pokazuje, jak wykonywać modyfikacje warunkowe za pomocą biblioteki klienta Java.

  private static void run() throws IOException {
    // Create a test event.
    Event event = Utils.createTestEvent(client, "Test Event");
    System.out.println(String.format("Event created: %s", event.getHtmlLink()));

    // Pause while the user modifies the event in the Calendar UI.
    System.out.println("Modify the event's description and hit enter to continue.");
    System.in.read();

    // Modify the local copy of the event.
    event.setSummary("Updated Test Event");

    // Update the event, making sure that we don't overwrite other changes.
    int numAttempts = 0;
    boolean isUpdated = false;
    do {
      Calendar.Events.Update request = client.events().update("primary", event.getId(), event);
      request.setRequestHeaders(new HttpHeaders().setIfMatch(event.getEtag()));
      try {
        event = request.execute();
        isUpdated = true;
      } catch (GoogleJsonResponseException e) {
        if (e.getStatusCode() == 412) {
          // A 412 status code, "Precondition failed", indicates that the etag values didn't
          // match, and the event was updated on the server since we last retrieved it. Use
          // {@link Calendar.Events.Get} to retrieve the latest version.
          Event latestEvent = client.events().get("primary", event.getId()).execute();

          // You may want to have more complex logic here to resolve conflicts. In this sample we're
          // simply overwriting the summary.
          latestEvent.setSummary(event.getSummary());
          event = latestEvent;
        } else {
          throw e;
        }
      }
      numAttempts++;
    } while (!isUpdated && numAttempts <= MAX_UPDATE_ATTEMPTS);

    if (isUpdated) {
      System.out.println("Event updated.");
    } else {
      System.out.println(String.format("Failed to update event after %d attempts.", numAttempts));
    }
  }

Pobieranie warunkowe

Jeśli chcesz pobrać zasób tylko wtedy, gdy uległ on zmianie od czasu ostatniego pobrania, możesz określić nagłówek If-None-Match, który zawiera wartość tagu ETag z poprzedniego pobrania. Jeśli wpis (a tym samym jego tag ETag) uległ zmianie od czasu ostatniego pobrania, zostanie zwrócona nowa wersja zasobu z nowym tagiem ETag. W przeciwnym razie otrzymasz kod odpowiedzi 304 (Not Modified).

Poniższy fragment przykładowego kodu pokazuje, jak wykonywać pobieranie warunkowe za pomocą biblioteki klienta Java.

  private static void run() throws IOException {
    // Create a test event.
    Event event = Utils.createTestEvent(client, "Test Event");
    System.out.println(String.format("Event created: %s", event.getHtmlLink()));

    // Pause while the user modifies the event in the Calendar UI.
    System.out.println("Modify the event's description and hit enter to continue.");
    System.in.read();

    // Fetch the event again if it's been modified.
    Calendar.Events.Get getRequest = client.events().get("primary", event.getId());
    getRequest.setRequestHeaders(new HttpHeaders().setIfNoneMatch(event.getEtag()));
    try {
      event = getRequest.execute();
      System.out.println("The event was modified, retrieved latest version.");
    } catch (GoogleJsonResponseException e) {
      if (e.getStatusCode() == 304) {
        // A 304 status code, "Not modified", indicates that the etags match, and the event has
        // not been modified since we last retrieved it.
        System.out.println("The event was not modified, using local version.");
      } else {
        throw e;
      }
    }
  }