İstekleri Gruplama

Bu belgede, istemcinizin kurması gereken HTTP bağlantılarının sayısını azaltmak için API çağrılarını nasıl toplu olarak yapacağınız gösterilmektedir.

Bu belge özellikle bir HTTP isteği göndererek toplu istek oluşturmakla ilgilidir. Bunun yerine, toplu istek yapmak için bir Google istemci kitaplığı kullanıyorsanız istemci kitaplığının dokümanlarına bakın.

Genel bakış

İstemcinizin yaptığı her HTTP bağlantısı, belirli miktarda ek yüke neden olur. Google Classroom API'si, istemcinizin tek bir HTTP isteğine birkaç API çağrısı koymasına olanak tanımak için toplu işlemi destekler.

Gruplandırmayı kullanmak isteyebileceğiniz durumlara örnekler:

  • Çok sayıda kursun öğrenci listelerini alma.
  • Toplu ders oluşturma veya güncelleme.
  • Çok sayıda ders listesi eklemek.
  • Çok sayıda kullanıcı için kurs listeleri alma.

Her durumda, her bir çağrıyı ayrı ayrı göndermek yerine tek bir HTTP isteği altında gruplandırabilirsiniz. Dahili tüm istekler aynı Google API'sine gitmelidir.

Tek bir toplu istekte 50 çağrıyla sınırlandırılırsınız. Bundan daha fazla çağrı yapmanız gerekiyorsa birden fazla toplu istek kullanın.

Not: Google Classroom API'sının toplu işlem sistemi, OData toplu işleme sistemiyle aynı söz dizimini kullanır ancak anlamlar farklıdır.

Grup ayrıntıları

Toplu istek, birden fazla API çağrısının tek bir HTTP isteğinde birleştirilmesinden oluşur. Bu çağrı, API keşif belgesinde belirtilen batchPath öğesine gönderilebilir. Varsayılan yol /batch/api_name/api_version şeklindedir. Bu bölümde toplu söz dizimi ayrıntılı olarak açıklanmaktadır; daha sonra bir örnek iletilecektir.

Not: Toplu olarak toplanan bir n istek kümesi, kullanım sınırınıza tek bir istek olarak değil, n istek olarak dahil edilir. Toplu istek, işlenmeden önce bir istek grubuna ayrılır.

Toplu isteğin biçimi

Toplu istek, multipart/mixed içerik türünü kullanan birden fazla Google Classroom API çağrısı içeren tek bir standart HTTP isteğidir. Bu ana HTTP isteğinde, parçaların her biri iç içe yerleştirilmiş bir HTTP isteği içerir.

Her bölüm kendi Content-Type: application/http HTTP başlığıyla başlar. İsteğe bağlı Content-ID üst bilgisi de olabilir. Bununla birlikte, parça başlıkları sadece parçanın başlangıcını belirtmek için yer alır; iç içe yerleştirilmiş istekten ayrıdır. Sunucu toplu isteğin sarmalamasını ayrı isteklere açtıktan sonra parça başlıkları yoksayılır.

Her bir parçanın gövdesi de kendi yüklemi, URL'si, başlıkları ve gövdesi ile eksiksiz bir HTTP isteğidir. HTTP isteği, yalnızca URL'nin yol kısmını içermelidir. Toplu isteklerde tam URL'lere izin verilmez.

Content-Type gibi Content- üstbilgileri hariç, dış toplu isteğin HTTP üst bilgileri gruptaki her istek için geçerlidir. Hem dış istekte hem de bağımsız bir çağrıda belirli bir HTTP üst bilgisi belirtirseniz bağımsız çağrı başlığının değeri, dış toplu istek başlığının değerini geçersiz kılar. Tek bir aramanın üstbilgileri yalnızca söz konusu arama için geçerlidir.

Örneğin, belirli bir çağrı için bir Yetkilendirme başlığı sağlarsanız bu üstbilgi yalnızca söz konusu çağrı için geçerli olur. Dış istek için bir Yetkilendirme üst bilgisi sağlarsanız bu üstbilgi kendi Yetkilendirme üstbilgileriyle geçersiz kılınmadığı sürece, ayrı ayrı tüm çağrılar için geçerli olur.

Sunucu toplu isteği aldığında, dış isteğin sorgu parametrelerini ve başlıklarını (uygun olduğu şekilde) her bir parçaya uygular ve ardından her bir bölümü ayrı bir HTTP isteği gibi değerlendirir.

Toplu isteğe yanıt

Sunucunun yanıtı, multipart/mixed içerik türüne sahip tek bir standart HTTP yanıtıdır; her bölüm, toplu istekteki isteklerden birine, isteklerle aynı sırayla verilen yanıttır.

İstekteki bölümler gibi her yanıt bölümü de durum kodu, başlıklar ve gövde metni dahil eksiksiz bir HTTP yanıtı içerir. İstekteki bölümlerde olduğu gibi, her yanıt bölümünün önünde, bölümün başlangıcını belirten bir Content-Type başlığı bulunur.

İsteğin belirli bir bölümünde Content-ID başlığı varsa, yanıtın karşılık gelen bölümü, aşağıdaki örnekte gösterildiği gibi, orijinal değerin önünde response- dizesiyle birlikte eşleşen bir Content-ID başlığına sahiptir.

Not: Sunucu, çağrılarınızı herhangi bir sırada gerçekleştirebilir. Bu kodların sizin belirttiğiniz sırada yürütülmesine gerek yoktur. Belirli bir sırada iki çağrının gerçekleşmesini istiyorsanız bunları tek bir istekte gönderemezsiniz. Bunun yerine, ilk aramayı tek başına gönderin ve ardından ikinciyi göndermeden önce ilk aramanın yanıtını bekleyin.

Örnek

Aşağıdaki örnekte, Google Classroom API ile toplu hale getirme kullanımı gösterilmektedir.

Örnek toplu istek

POST https://classroom.googleapis.com/batch HTTP/1.1
Authorization: Bearer your_auth_token
Content-Type: multipart/mixed; boundary=batch_foobarbaz
Content-Length: total_content_length

--batch_foobarbaz
Content-Type: application/http
Content-Transfer-Encoding: binary
MIME-Version: 1.0
Content-ID: <item1:12930812@classroom.example.com>

PATCH /v1/courses/134529639?updateMask=name HTTP/1.1
Content-Type: application/json; charset=UTF-8
Authorization: Bearer your_auth_token

{
  "name": "Course 1"
}
--batch_foobarbaz
Content-Type: application/http
Content-Transfer-Encoding: binary
MIME-Version: 1.0
Content-ID: <item2:12930812@classroom.example.com>

PATCH /v1/courses/134529901?updateMask=section HTTP/1.1
Content-Type: application/json; charset=UTF-8
Authorization: Bearer your_auth_token
{
  "section": "Section 2"
}
--batch_foobarbaz--

Örnek toplu yanıt

Bu, önceki bölümde verilen örnek isteğe verilen yanıttır.

HTTP/1.1 200
Content-Length: response_total_content_length
Content-Type: multipart/mixed; boundary=batch_foobarbaz

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item1:12930812@classroom.example.com>

HTTP/1.1 200 OK
Content-Type application/json
Content-Length: response_part_1_content_length

{
  "id": "134529639",
  "name": "Course 1",
  "section": "Section 1",
  "ownerId": "116269102540619633451",
  "creationTime": "2015-06-25T14:23:56.535Z",
  "updateTime": "2015-06-25T14:33:06.583Z",
  "enrollmentCode": "6paeflo",
  "courseState": "PROVISIONED",
  "alternateLink": "http://classroom.google.com/c/MTM0NTI5NjM5"
}
--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item2:12930812@classroom.example.com>

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: response_part_2_content_length

{
  "id": "134529901",
  "name": "Course 1",
  "section": "Section 2",
  "ownerId": "116269102540619633451",
  "creationTime": "2015-06-25T14:23:08.761Z",
  "updateTime": "2015-06-25T14:33:06.490Z",
  "enrollmentCode": "so75ha5",
  "courseState": "PROVISIONED",
  "alternateLink": "http://classroom.google.com/c/MTM0NTI5OTAx"
}
--batch_foobarbaz--

İstemci kitaplıklarını kullanma

Aşağıdaki kod örnekleri, Google API'leri istemci kitaplıklarını kullanarak toplu isteklerin nasıl oluşturulacağını göstermektedir. Kitaplıkları yükleme ve kurma hakkında daha fazla bilgi için ilgili hızlı başlangıç kılavuzlarına göz atın.

.NET

classroom/snippets/ClassroomSnippets/BatchAddStudents.cs
using Google;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Classroom.v1;
using Google.Apis.Classroom.v1.Data;
using Google.Apis.Requests;
using Google.Apis.Services;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace ClassroomSnippets
{
    // Class to demonstrate the use of Classroom Batch Add Students API
    public class BatchAddStudents
    {
        /// <summary>
        /// Add multiple students in a specified course.
        /// </summary>
        /// <param name="courseId">Id of the course to add students.</param>
        /// <param name="studentEmails">Email address of the students.</param>
        public static void ClassroomBatchAddStudents(string courseId,
            List<string> studentEmails)
        {
            try
            {
                /* Load pre-authorized user credentials from the environment.
                 TODO(developer) - See https://developers.google.com/identity for 
                 guides on implementing OAuth2 for your application. */
                GoogleCredential credential = GoogleCredential.GetApplicationDefault()
                    .CreateScoped(ClassroomService.Scope.ClassroomRosters);

                // Create Classroom API service.
                var service = new ClassroomService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Classroom Snippets"
                });

                var batch = new BatchRequest(service, "https://classroom.googleapis.com/batch");
                BatchRequest.OnResponse<Student> callback = (student, error, i, message) =>
                {
                    if (error != null)
                    {
                        Console.WriteLine("Error adding student to the course: {0}", error.Message);
                    }
                    else
                    {
                        Console.WriteLine("User '{0}' was added as a student to the course.",
                            student.Profile.Name.FullName);
                    }
                };
                foreach (var studentEmail in studentEmails)
                {
                    var student = new Student() {UserId = studentEmail};
                    var request = service.Courses.Students.Create(student, courseId);
                    batch.Queue<Student>(request, callback);
                }

                Task.WaitAll(batch.ExecuteAsync());
            }
            catch (Exception e)
            {
                // TODO(developer) - handle error appropriately
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else if (e is GoogleApiException)
                {
                    Console.WriteLine("Course does not exist.");
                }
                else
                {
                    throw;
                }
            }
        }
    }
}

Java

classroom/snippets/src/main/java/BatchAddStudents.java
import com.google.api.client.googleapis.batch.BatchRequest;
import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.classroom.Classroom;
import com.google.api.services.classroom.ClassroomScopes;
import com.google.api.services.classroom.model.Student;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/* Class to demonstrate the use of Classroom Batch Add Students API */
public class BatchAddStudents {

  /* Scopes required by this API call. If modifying these scopes, delete your previously saved
  tokens/ folder. */
  static ArrayList<String> SCOPES =
      new ArrayList<>(Arrays.asList(ClassroomScopes.CLASSROOM_ROSTERS));

  /**
   * Add multiple students in a specified course.
   *
   * @param courseId - Id of the course to add students.
   * @param studentEmails - Email address of the students.
   * @throws IOException - if credentials file not found.
   * @throws GeneralSecurityException - if a new instance of NetHttpTransport was not created.
   */
  public static void batchAddStudents(String courseId, List<String> studentEmails)
      throws GeneralSecurityException, IOException {

    // Create the classroom API client.
    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    Classroom service =
        new Classroom.Builder(
                HTTP_TRANSPORT,
                GsonFactory.getDefaultInstance(),
                ClassroomCredentials.getCredentials(HTTP_TRANSPORT, SCOPES))
            .setApplicationName("Classroom samples")
            .build();

    BatchRequest batch = service.batch();
    JsonBatchCallback<Student> callback =
        new JsonBatchCallback<>() {
          public void onSuccess(Student student, HttpHeaders responseHeaders) {
            System.out.printf(
                "User '%s' was added as a student to the course.\n",
                student.getProfile().getName().getFullName());
          }

          public void onFailure(GoogleJsonError error, HttpHeaders responseHeaders) {
            System.out.printf("Error adding student to the course: %s\n", error.getMessage());
          }
        };
    for (String studentEmail : studentEmails) {
      Student student = new Student().setUserId(studentEmail);
      service.courses().students().create(courseId, student).queue(batch, callback);
    }
    batch.execute();
  }
}

2.999

classroom/snippets/src/ClassroomBatchAddStudents.php
use Google\Client;
use Google\Service\Classroom;
use Google\Service\Classroom\Student;
use Google\Service\Exception;

function batchAddStudents($courseId, $studentEmails)
{
    /* Load pre-authorized user credentials from the environment.
    TODO(developer) - See https://developers.google.com/identity for
     guides on implementing OAuth2 for your application. */
    $client = new Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope("https://www.googleapis.com/auth/classroom.profile.emails");
    $service = new Classroom($client);
    $service->getClient()->setUseBatch(true);
    //create batch
    $batch = $service->createBatch();
    foreach ($studentEmails as $studentEmail) {
        $student = new Student([
            'userId' => $studentEmail
        ]);
        $request = $service->courses_students->create($courseId, $student);
        $requestId = $studentEmail;
        $batch->add($request, $requestId);
    }
    //executing request
    $results = $batch->execute();
    foreach ($results as $responseId => $student) {
        $studentEmail = substr($responseId, strlen('response-') + 1);
        if ($student instanceof Exception) {
            $e = $student;
            printf("Error adding user '%s' to the course: %s\n", $studentEmail,
                $e->getMessage());
        } else {
            printf("User '%s' was added as a student to the course.\n",
                $student->profile->name->fullName, $courseId);
        }
    }
    $service->getClient()->setUseBatch(false);
    return $results;
}

Python

course_id = '123456'
student_emails = ['alice@example.edu', 'bob@example.edu']
def callback(request_id, response, exception):
    if exception is not None:
        print 'Error adding user "{0}" to the course course: {1}'.format(
            request_id, exception)
    else:
        print 'User "{0}" added as a student to the course.'.format(
            response.get('profile').get('name').get('fullName'))
batch = service.new_batch_http_request(callback=callback)
for student_email in student_emails:
    student = {
        'userId': student_email
    }
    request = service.courses().students().create(courseId=course_id,
                                                  body=student)
    batch.add(request, request_id=student_email)
batch.execute(http=http)