자바스크립트 클라이언트 라이브러리 사용 (v2.0)

경고: 이 페이지는 Google의 이전 API인 Google Data API에 관한 것으로, Google Data API 디렉터리에 표시된 API 중 상당수가 최신 API로 대체된 API입니다. 특정 새 API에 대한 자세한 내용은 새 API 문서를 참조하세요. 최신 API를 사용하여 요청을 승인하는 방법은 Google 계정 인증 및 승인을 참고하세요.

이 문서에서는 자바스크립트 클라이언트 라이브러리를 사용하여 Google 데이터 API 쿼리를 보내고 반환된 응답을 해석하는 방법을 설명합니다.

Google은 다양한 프로그래밍 언어로 된 클라이언트 라이브러리 세트를 제공하여 데이터 API가 있는 서비스와 상호작용합니다. 이러한 라이브러리를 사용하여 API 요청을 구성하고 서비스로 보내고 응답을 받을 수 있습니다.

이 문서에서는 자바스크립트 클라이언트 라이브러리 사용에 관한 일반적인 정보와 몇 가지 일반적인 사용 사례를 제공합니다.

대상

이 문서는 Google 데이터 서비스와 상호작용할 수 있는 클라이언트 애플리케이션을 작성하려는 자바스크립트 프로그래머를 대상으로 합니다.

이 문서에서는 사용자가 Google Data API 프로토콜에 관한 일반적인 개념을 이해하고 있다고 가정합니다. 또한 개발자가 자바스크립트로 프로그래밍하는 방법을 알고 있다고 가정합니다.

클라이언트 라이브러리에서 제공하는 클래스 및 메서드에 대한 자세한 내용은 자바스크립트 클라이언트 라이브러리 API 참조(JSdoc 형식)를 참고하세요.

이 문서는 순서대로 읽어야 하며 각 예시는 이전 예시를 바탕으로 작성되었습니다.

이용약관

자바스크립트 클라이언트 라이브러리를 사용하는 경우 Google 자바스크립트 클라이언트 라이브러리 이용약관을 준수하는 데 동의합니다.

데이터 모델 및 제어 흐름 개요

자바스크립트 클라이언트 라이브러리는 클래스 집합을 사용하여 Google Data API에서 사용하는 요소를 나타냅니다.

참고: 데이터의 기본 표현은 JSON이지만 클라이언트 라이브러리는 추상화 레이어를 제공하므로 JSON 데이터를 직접 사용할 필요가 없습니다. 클라이언트 라이브러리 없이 JSON으로 직접 작업하려면 Google Data API에 JSON 사용을 참고하세요.

라이브러리는 Data API가 있는 서비스에 데이터를 비동기식으로 전송하고 데이터를 수신할 수 있는 메서드를 제공합니다. 예를 들어 google.gdata.calendar.CalendarService.getEventsFeed() 메서드는 Google Calendar로 피드 요청을 보냅니다. 전달하는 매개변수 중 하나는 콜백이라고도 하는 연속 함수입니다. 서비스는 연속 함수를 호출하여 JSON 형식의 피드를 반환합니다. 그러면 클라이언트는 다양한 get 메서드를 호출하여 데이터를 자바스크립트 객체 형태로 사용할 수 있습니다.

새 항목을 추가하려면 클라이언트 라이브러리의 클래스와 메서드를 사용하여 항목을 만든 다음 feed.insertEntry() 메서드를 호출하여 새 항목을 서비스로 전송합니다. 항목이 계속 추가되면 서비스에서 호출하는 연속 함수를 제공합니다.

자바스크립트가 처음이라면 제어 흐름이 조금 혼란스러울 수 있습니다. getEventsFeed() 또는 insertEntry()과 같은 메서드를 호출하면 대부분의 경우 스크립트가 종료됩니다. 서비스가 요청된 데이터를 반환하면 연속 함수에서 실행이 재개됩니다. 따라서 클라이언트가 반환된 데이터에 수행하는 모든 작업은 연속 함수에서 해야 하거나 이 함수에서 호출되어야 합니다. 일부 변수를 여러 함수에서 사용하려면 전역 변수를 만들어야 할 수 있습니다.

이러한 프로그래밍 스타일에 관한 자세한 내용은 위키백과에서 '연속 통과 스타일'을 참고하세요.

지원되는 환경 정보

현재 Google은 브라우저의 웹페이지에서 실행되는 자바스크립트 클라이언트 애플리케이션만 지원합니다. 현재 지원되는 브라우저는 다음과 같습니다.

  • Firefox 2.x 및 3.x
  • Internet Explorer 6, 7, 8
  • Safari 3.x 및 4.x
  • Chrome (모든 버전)

자바스크립트 클라이언트 라이브러리는 서비스 서버와의 모든 통신을 처리합니다. 숙련된 JS 개발자라면 '동일한 출처 정책은 어떨까요?'라고 생각할 수 있습니다. 자바스크립트 클라이언트 라이브러리를 사용하면 클라이언트가 브라우저 보안 모델을 준수하면서 모든 도메인에서 Google 데이터 요청을 보낼 수 있습니다.

Google Data API 인증에 관한 개요는 Google Data API 인증 개요를 참고하세요. 이 문서의 나머지 부분에서는 이 시스템의 기본 사항을 잘 알고 있다고 가정합니다.

샘플 클라이언트 애플리케이션

자바스크립트 클라이언트 라이브러리가 작동하는 모습을 보려면 샘플 페이지를 방문하세요.

튜토리얼 및 예시

다음 예는 자바스크립트 클라이언트 라이브러리를 사용하여 다양한 데이터 API 요청을 보내는 방법을 보여줍니다.

좀 더 구체적으로 만들기 위해 이 예시에서는 Google Calendar와 같은 특정 서비스와 상호작용하는 방법을 보여줍니다. 이 예제를 다른 서비스에 맞춰 조정할 수 있도록 Calendar가 다른 Google 서비스와 다른 위치를 알려 드리겠습니다. Calendar에 관한 자세한 내용은 Google Calendar Data API 문서를 참고하세요.

라이브러리 로드

클라이언트가 클라이언트 라이브러리를 사용하려며 서버로부터 클라이언트 라이브러리 코드를 요청해야 합니다.

먼저 HTML 문서의 <head> 섹션에 <script> 태그를 사용하여 Google AJAX API 로더를 가져옵니다.

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

라이브러리를 미리 로드하여 Google 서버로의 왕복을 최소화하고 지연 시간을 줄일 수 있습니다. google.load()를 사용하지 않고 Google AJAX API 로더에서 직접 특정 패키지를 미리 로드하려면 다음을 사용하세요.

<script type="text/javascript"
      src="https://www.google.com/jsapi?autoload=%7Bmodules%3A%5B%7Bname%3Agdata%2Cversion%3A2.x%2Cpackages%3A%5Bblogger%2Ccontacts%5D%7D%5D%7D"></script>

참고: 스크립트의 src URL은 완전히 URL 인코딩되어야 합니다. 예를 들어 이전 예는
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={modules:[{name:gdata,version:2.x,packages:[blogger,contacts]}]}"></script>입니다.

모듈을 자동 로드하지 않는 경우 공통 로더를 가져온 후 자바스크립트 설정 코드의 다음 예를 사용하여 Google 데이터 클라이언트 라이브러리를 로드할 수 있습니다. 이 호출은 HTML 문서의 <head> 섹션 (또는 HTML 문서의 <head> 섹션에 있는 <script> 태그를 사용하여 포함된 자바스크립트 파일)에서 실행해야 합니다.

google.load("gdata", "2");

또는 전체 라이브러리 대신 특정 서비스를 요청할 수도 있습니다. 이 예에서는 Blogger 및 주소록 패키지만 다운로드합니다.

google.load("gdata", "2.x", {packages: ["blogger", "contacts"]});

google.load()의 두 번째 매개변수는 자바스크립트 클라이언트 라이브러리의 요청된 버전 번호입니다.Google의 버전 번호 지정 체계는 Google 지도 API에서 사용하는 모델을 모델링합니다. 가능한 버전 번호와 그 의미는 다음과 같습니다.

"1"
메이저 버전 1의 마지막에서 두 번째 버전
"1.x"
메이저 버전 1의 최신 버전입니다.
"1.s"
메이저 버전 1의 최신 안정화 버전입니다. Google은 개발자로부터 받은 의견을 바탕으로 클라이언트 라이브러리의 특정 버전을 '안정적'이라고 선언합니다. 그러나 해당 버전에 최신 지형지물이 없을 수 있습니다.
"1.0", "1.1" 등
라이브러리의 특정 버전으로, 지정된 주 버전 및 부 버전 번호가 포함됩니다.

google.load()를 호출한 후에는 페이지 로드가 완료될 때까지 로더에 지시하고 코드를 호출하도록 로더에 지시해야 합니다.

google.setOnLoadCallback(getMyFeed);

여기서 getMyFeed()는 이 문서의 다음 섹션에 정의된 함수입니다. onload 핸들러를 <body> 요소에 연결하는 대신 이 접근 방식을 사용합니다.

인증되지 않은 피드 요청

인증되지 않은 피드를 요청하려면 자바스크립트 파일 또는 HTML 파일의 <script> 태그에 다음 코드를 추가하세요.

다음 코드에서는 이전 섹션에서 설명한 대로 AJAX API 로더를 통해 getMyFeed()가 먼저 호출됩니다.

setupMyService()를 호출하여 CalendarService 객체로 표시되는 연결을 Google Calendar에 생성합니다. 모듈화를 위해 서비스 생성 코드를 별도의 함수로 가져왔으며, 나중에 인증 선택에 따라 setupMyService() 함수를 수정합니다.

서비스를 설정한 후 getMyFeed()가 클라이언트 라이브러리의 getEventsFeed() 메서드를 호출하여 피드를 요청합니다.

피드 URL을 이후 변수에 사용할 수 있도록 전역 변수에 지정하고 있습니다. 이 예에서는 liz@gmail.com이라는 사용자에 대해 공개 (인증되지 않은) 피드 URL을 사용합니다. 사용자의 이메일 주소 대신 default를 사용하여 인증된 사용자를 나타낼 수도 있습니다.

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/public/full";

function setupMyService() {
  var myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
  return myService;
}

function getMyFeed() {
  myService = setupMyService();

  myService.getEventsFeed(feedUrl, handleMyFeed, handleError);
}

이후 함수에서 쉽게 사용할 수 있도록 myService를 전역 변수로 만듭니다.

내 클라이언트에서 위 코드를 사용하려면 공개적으로 공유하는 캘린더가 있는 Calendar 계정에 실제 사용자의 이메일 주소를 사용해야 합니다.

참고: 새 CalendarService 객체를 만들 때 클라이언트 라이브러리는 google.gdata.client.init()라는 메서드를 호출하여 클라이언트가 실행 중인 브라우저가 지원되는지 확인합니다. 오류가 있으면 클라이언트 라이브러리가 사용자에게 오류 메시지를 표시합니다. 이러한 종류의 오류를 직접 처리하려면 서비스를 만들기 전에 google.gdata.client.init(handleInitError)를 명시적으로 호출하면 됩니다. 여기서 handleInitError()는 함수입니다. init 오류가 발생하면 함수에서 표준 Error 객체를 수신합니다. 이 객체로 원하는 작업을 할 수 있습니다.

getEventsFeed() 호출에서 두 번째 인수는 콜백 함수인 handleMyFeed입니다. 아래를 참고하세요. Google Calendar에서 요청을 처리한 다음 요청이 성공하면 '피드 루트' 객체를 요청된 피드에 포함합니다. 피드 루트는 피드가 포함된 컨테이너 객체입니다.

getEventsFeed()의 세 번째 인수는 선택적 오류 처리 함수입니다. 클라이언트 라이브러리에 오류가 발생하면 성공 콜백 함수 대신 지정된 오류 핸들러를 호출합니다. 클라이언트 라이브러리가 오류 핸들러에 인수로 전달하는 객체는 추가 cause 속성이 있는 자바스크립트 Error 객체의 인스턴스입니다.

다음은 콜백 함수와 오류 핸들러의 간단한 버전입니다.

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
}

function handleError(e) {
  alert("There was an error!");
  alert(e.cause ? e.cause.statusText : e.message);
}

오류를 사용자에게 표시하기만 하면 오류가 처리됩니다. 클라이언트의 오류 핸들러가 더 복잡할 수 있습니다. 상황에 따라서는 지정된 이유가 없을 수도 있으므로 이 경우 예시의 오류 핸들러는 표준 message 속성을 표시하도록 대체합니다.

이 코드는 인증을 하지 않으므로 공개 피드를 가져올 때만 사용할 수 있습니다.

인증하는 중

자바스크립트 클라이언트 라이브러리는 두 가지 모드로 사용할 수 있습니다. 가젯 작성 시 인증을 위해 OAuth 프록시라는 기능을 사용합니다. 독립형 자바스크립트 애플리케이션에서 액세스하는 경우 AuthSub 인증 시스템을 사용합니다. 인증에 대한 자세한 내용은 Google Data API 인증 개요 문서를 참고하세요. 이 섹션의 나머지 부분에서는 이 시스템의 기본 작동 원리를 잘 알고 있다고 가정합니다.

이 문서에 제공된 샘플 코드로 인증을 사용하려면 먼저 피드 URL을 공개에서 비공개로 변경하세요.

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/private/full";

AuthSub으로 웹 클라이언트에서 인증

Google의 '자바스크립트용 AuthSub' 인증 시스템은 더 이상 제공되지 않습니다.

대신 클라이언트 측 애플리케이션용 OAuth 2.0을 사용하는 것이 좋습니다.

OAuth 프록시로 가젯에서 인증하기

다음은 가젯 인증 과정 동안 진행되는 작업에 대한 간략한 개요입니다.

  1. 가젯이 처음으로 로드되고 Google 데이터 API 중 하나를 사용하여 사용자 데이터에 액세스하려고 합니다.
  2. 사용자가 아직 데이터 액세스 권한을 부여하지 않았으므로 요청이 실패합니다. 응답 객체에는 OAuth 승인 페이지의 URL (response.oauthApprovalUrl)이 포함됩니다. 가젯은 해당 URL로 새 창을 실행하는 방법을 제공해야 합니다.
  3. 승인 페이지에서 사용자가 가젯에 대한 액세스를 허용/거부하도록 선택합니다. 성공하면 사용자는 지정된 oauth_callback 페이지로 이동합니다. 최상의 사용자 환경을 위해 http://oauth.gmodules.com/gadgets/oauthcallback를 사용하세요.
  4. 그런 다음 사용자가 팝업 창을 닫습니다. 사용자가 승인했음을 가젯에 알리기 위해 Google은 승인 창 닫기를 감지하는 데 사용할 수 있는 팝업 핸들러를 제공합니다. 또는 이 창이 닫힌 후 사용자가 수동으로 클릭할 수 있는 링크 (예: '액세스를 승인함')를 가젯에 표시할 수 있습니다.
  5. 가젯이 사용자의 데이터를 다시 요청하여 Google Data API에 다시 액세스를 시도합니다. 이 시도가 성공했습니다.
  6. 가젯이 인증되었으며 정상적으로 작동할 수 있습니다.

가젯의 <ModulePrefs> 섹션에 <OAuth> 요소를 추가합니다.

<ModulePrefs>
...
<OAuth>
  <Service name="google">
    <Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" /> 
    <Request url="https://www.google.com/accounts/OAuthGetRequestToken?
                  scope=http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/" method="GET" /> 
    <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?
                        oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> 
  </Service>
</OAuth>
...
</ModulePrefs>

이 섹션에서는 다음 쿼리 매개변수를 변경합니다.

  • scope

    요청 URL의 필수 매개변수입니다. 가젯은 이 매개변수에 사용된 scope의 데이터에만 액세스할 수 있습니다. 이 예에서 가젯은 Blogger 및 캘린더 데이터에 액세스합니다. 가젯은 단일 범위 또는 여러 범위에 대한 데이터를 요청할 수 있습니다 (이 예의 경우처럼).

  • oauth_callback

    승인 URL의 선택적 매개변수입니다. 사용자가 데이터에 대한 액세스를 승인하면 OAuth 승인 페이지가 이 URL로 리디렉션됩니다. 이 매개변수를 그대로 두거나 '승인된 페이지'로 설정하거나 http://oauth.gmodules.com/gadgets/oauthcallback를 사용할 수 있습니다. 후반부에서 사용자가 처음으로 라이브러리를 설치할 때 최상의 사용자 환경을 제공합니다. 해당 페이지는 팝업 창을 자동으로 닫는 자바스크립트 스니펫을 제공합니다.

그런 다음 가젯의 <Content> 섹션에 자바스크립트 클라이언트 라이브러리를 로드합니다. 이전 예시의 setupMyService() 함수를 수정하여 서비스 객체의 useOAuth() 메서드를 호출합니다. 이렇게 하면 AuthSub가 아닌 OAuth 프록시를 사용하여 인증하도록 가젯에 지시합니다. 아래 템플릿을 사용하면 쉽게 시작할 수 있습니다.

<Content type="html">
<![CDATA[
  ...
  <script src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
    var myService = null;
    
    function setupMyService() {
      myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
      myService.useOAuth('google');
      fetchData();
    }
    
    function initGadget() {
      google.load('gdata', '2.x');
      google.setOnLoadCallback(setupMyService);
    }

    function fetchData() {            
      var callback = function(response) {
        if (response.oauthApprovalUrl) {
        
          // TODO: Display "Sign in" link (response.oauthApprovalUrl contains the URL) 
          
        } else if (response.feed) {
        
          // TODO: show results
          
        } else {
        
          // TODO: handle the error
          
        }
      };

      myService.getEventsFeed('http://www.google.com/calendar/feeds/default/public/full', callback, callback);
    }
    
    gadgets.util.registerOnLoadHandler(initGadget);
  </script>
  ...
]]> 
</Content>

google.accounts.user.login(scope) 호출이 삭제되었습니다. 프록시가 인증을 처리합니다.

fetchData()에 포함되어야 하는 내용을 비롯하여 Google Data API 가젯 작성에 대한 자세한 내용은 Google 데이터 가젯 만들기에 대한 도움말을 참조하거나 전체 OAuth 가젯 작성 문서를 확인하세요.

새 항목 삽입

새 캘린더 일정을 만들려면 새 함수를 호출하도록 handleMyFeed() 함수의 끝을 수정하여 이전 예의 실행을 계속합니다.

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
  insertIntoMyFeed(myResultsFeedRoot);
}

새 함수에서 먼저 CalendarEventEntry 생성자를 사용하여 새 항목을 만듭니다. 그런 다음 항목을 삽입하여 삽입이 완료되면 서비스에서 호출할 콜백을 제공합니다.

function insertIntoMyFeed(feedRoot) {
  var newEntry = new google.gdata.calendar.CalendarEventEntry({
      authors: [{
        name: "Elizabeth Bennet",
        email: "liz@gmail.com"
      }],
      title: {
        type: 'text', 
        text: 'Tennis with Darcy'
      },
      content: {
        type: 'text', 
        text: 'Meet for a quick lesson'
      },
      locations: [{
        rel: "g.event",
        label: "Event location",
        valueString: "Netherfield Park tennis court"
      }],
      times: [{
        startTime: google.gdata.DateTime.fromIso8601("2007-09-23T18:00:00.000Z"),
        endTime: google.gdata.DateTime.fromIso8601("2007-09-23T19:00:00.000Z")
      }]
  });
  feedRoot.feed.insertEntry(newEntry, handleMyInsertedEntry, handleError);
}

생성자에 사용된 각 객체 속성의 이름은 해당 속성에 사용된 setter 메서드의 이름과 일치합니다. (예를 들어 상응하는 JSON 필드 이름과 일치시키는 대신)

또한 startTimeendTime에 ISO 8601 날짜 및 시간 문자열만 제공할 수 없습니다. 먼저 fromIso8601() 메서드를 통해 이러한 문자열을 실행해야 합니다.

서비스는 삽입된 항목의 사본을 entryRoot 객체로 반환하고 이 객체를 콜백에 전달합니다.

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
}

특정 항목 요청

특정 항목을 요청하려면 먼저 handleMyInsertedEntry() 함수를 수정하여 새 항목 요청 함수를 호출합니다.

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
  requestMySpecificEntry(insertedEntryRoot.entry.getSelfLink().getHref());
}

다음 코드를 사용하면 이전 예에서 삽입한 특정 항목을 요청할 수 있습니다.

이러한 일련의 예시에서 컨텍스트에서는 항목이 이미 제출된 항목을 반환했으므로 실제로 해당 항목을 가져올 필요는 없습니다. 하지만 항목의 URI를 알고 있을 때마다 동일한 기법을 적용할 수 있습니다.

function requestMySpecificEntry(entryURI) {
  myService.getEventsEntry(entryURI, handleMySpecificEntry, handleError);
}

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
}

이 예시는 getEventsFeed() 예와 본질적으로 동일하지만, 특정 항목을 가져오기 위해 서비스의 getEventEntry() 메서드를 호출하고 URI는 약간 다릅니다. 즉, 인증된 사용자의 기본 캘린더를 참조하는 데 '기본'을 사용하고 끝에 항목 ID가 있습니다.

또한 검색된 항목을 나중에 사용할 수 있어야 하므로 전역 변수에 복사합니다.

항목 검색

전체 텍스트 검색을 수행하려면 먼저 handleMySpecificEntry() 함수를 수정하여 새 검색 함수를 호출합니다.

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
  searchMyFeed();
}

그런 다음 검색에서 첫 번째 일치 항목을 검색하려면 다음 코드를 사용합니다.

function searchMyFeed() {
  var myQuery = new google.gdata.calendar.CalendarEventQuery(feedUrl);
  myQuery.setFullTextQuery("Tennis");
  myQuery.setMaxResults(10);
  myService.getEventsFeed(myQuery, handleMyQueryResults, handleError);
}

function handleMyQueryResults(myResultsFeedRoot) {
  if (myResultsFeedRoot.feed.getEntries()[0]) {
    alert("The first search-match entry's title is: " + myResultsFeedRoot.feed.getEntries()[0].getTitle().getText());
  }
  else {
    alert("There are no entries that match the search query.");
  }
}

항목 업데이트

기존 항목을 업데이트하려면 먼저 handleMyQueryResults() 끝에 다음 줄을 추가하여 새 업데이트 함수를 호출합니다.

  updateMyEntry();

다음 코드를 사용하세요. 이 예에서는 이전에 검색한 항목 (이전 예에서는 myEntryRoot라는 전역 객체에 포함)의 제목을 이전 텍스트('Tarnis with Darcy')에서 '중요 회의'로 변경합니다.

function updateMyEntry() {
  myEntryRoot.entry.getTitle().setText("Important meeting");
  myEntryRoot.entry.updateEntry(handleMyUpdatedEntry, handleError);
}

function handleMyUpdatedEntry(updatedEntryRoot) {
  alert("Entry updated. The new title is: " + updatedEntryRoot.entry.getTitle().getText());
}

모든 Calendar 메서드와 마찬가지로 updateEntry() 메서드는 항목을 업데이트하는 데 사용할 올바른 수정 URI를 자동으로 결정하므로 이 URI를 명시적으로 제공하지 않아도 됩니다.

항목 삭제

업데이트된 항목을 삭제하려면 먼저 handleMyUpdatedEntry()에 다음 줄을 추가합니다.

 deleteMyEntry(updatedEntryRoot);

다음 코드를 사용하세요.

function deleteMyEntry(updatedEntryRoot) {
  updatedEntryRoot.entry.deleteEntry(handleMyDeletedEntry, handleError);
}

function handleMyDeletedEntry() {
  alert("Entry deleted");
}

다시 deleteEntry() 메서드는 항목을 삭제하는 데 사용할 올바른 수정 URI를 자동으로 결정합니다.

반환되는 항목은 없습니다. 콜백이 호출되면 삭제가 성공한 것입니다. 삭제에 실패하면 deleteEntry()에서 handleMyDeletedEntry()를 호출하는 대신 handleError()를 호출합니다.

ETags 사용

참고: ETag는 Google 데이터 프로토콜 v2.0을 실행하는 서비스에서만 사용할 수 있습니다.

소개

Google 데이터 자바스크립트 클라이언트 버전 2에서는 ETag를 지원합니다. ETag는 특정 항목의 특정 버전을 지정하는 식별자입니다. 다음과 같은 두 가지 경우에 중요합니다.

  • '조건부 검색'은 클라이언트가 항목을 요청하고 서버는 클라이언트가 마지막으로 제출한 이후에 항목이 변경된 경우에만 항목을 전송합니다.
  • 여러 클라이언트가 의도치 않게 서로의 변경사항을 덮어쓰지 않도록 합니다. 클라이언트가 항목의 이전 ETag를 지정하는 경우 Data API가 업데이트와 삭제 실패를 유발함으로써 이 작업을 수행합니다.

ETag에는 두 가지 유형(약함과 강함)이 있습니다. 약한 ETag는 항상 W/로 시작합니다(예: W/"D08FQn8-eil7ImA9WxZbFEw"). 약한 ETag는 항목이 변경될 때 변경이 보장되지 않으므로 HTTP에서는 조건부 검색에만 사용할 수 있습니다. 강력한 ETag는 특정 항목의 특정 버전을 식별하며 조건부 검색이나 업데이트 또는 삭제 단계 중에 모두 사용하여 다른 클라이언트의 변경사항을 덮어쓰지 않도록 할 수 있습니다. 이러한 구분으로 인해 클라이언트 라이브러리에서 업데이트 또는 삭제 요청과 함께 취약한 ETag를 전송할 수 없습니다.

ETag는 서버 응답의 다음 두 위치에서 찾을 수 있습니다.

  • ETag HTTP 헤더
  • 피드/항목에서 gd:etag 속성으로 설정합니다.

서비스에서 버전 2를 지원하는 경우 각 피드와 항목 객체에 ETag 값을 가져오는 getEtag() 메서드가 있습니다.

자바스크립트 클라이언트는 요청에 ETag를 포함하는 두 가지 메서드를 지원합니다. 첫 번째는 새로운 opt_params 객체입니다. 클라이언트 라이브러리 버전 2의 모든 get/update/insert 함수에는 새로운 opt_params 매개변수가 있습니다. 이 객체는 요청 시 선택적 매개변수를 지정하는 데 사용됩니다. 'etag'는 유일하게 지원되는 선택적 매개변수입니다 (향후 다른 매개변수가 도입될 수도 있음). 예를 들어 다음과 같이 ETag를 EGET 요청에 추가할 수 있습니다.

var opt_params = {};
opt_params['etag'] = 'ETAG GOES HERE';
service.getFeed(uri, successHandler, errorHandler, opt_params);

피드/항목에서 setEtag() 메서드를 호출하여 피드 또는 항목 객체에 직접 ETag를 추가할 수도 있습니다.

ETag에 관한 자세한 내용은 GData 프로토콜 참조를 확인하세요.

ETag를 사용하여 데이터 가져오기

ETag는 데이터를 가져올 때 대역폭과 실행 시간을 줄이는 데 도움이 될 수 있습니다. ETag는 If-None-Match header:를 포함하는 GET 요청에 포함될 수 있습니다.

If-None-Match: ETAG GOES HERE

ETag가 피드 또는 항목의 현재 버전과 일치하면 서버에서 304 NOT MODIFIED 응답과 빈 본문으로 응답합니다. 그렇지 않으면 서버에서 200 OK 응답과 피드 또는 항목 데이터로 응답합니다.

요청 시 'etag' 매개변수를 포함하여 자바스크립트 클라이언트에서 ETag를 사용할 수 있습니다.

var etag = feed.getEtag(); // Feed loaded from a previous request
var opt_params = {};
opt_params['etag'] = etag;
service.getFeed(feedUrl, successHandler, errorHandler, opt_params);

조건부 검색에서는 효과적인 ETag와 취약한 ETag를 모두 사용할 수 있습니다. ETag가 일치하는 경우 오류 핸들러가 304 응답과 함께 호출됩니다.

function successHandler(feedRoot) {
  // 200 response
  // Update UI to display updates
}

function errorHandler(errorObj) {
  if (errorObj.cause.getStatus() == 304) {
    // 304 response, do nothing
  }
  // otherwise the response is some other error
}

자바스크립트 클라이언트에서 ETag를 사용하는 실용적 예시를 보려면 Blogger를 사용한 조건부 검색 샘플을 참고하세요. 이 샘플에서는 5초 간격으로 Blogger를 검색하여 블로그 업데이트를 확인합니다. 변경사항이 있으면 샘플이 게시물 목록을 업데이트합니다.

ETag를 사용하여 데이터 업데이트 및 삭제

업데이트/삭제 요청에 ETag를 사용하면 여러 클라이언트가 의도치 않게 서로의 변경사항을 덮어쓰지 않습니다. 이 경우 ETag는 If-Match 헤더와 함께 포함됩니다.

If-Match: ETAG GOES HERE

요청의 ETag가 서버의 ETag와 일치하면 업데이트/삭제가 성공한 것입니다. 하지만 ETag 불일치는 항목이 변경되었음을 나타내며 업데이트/삭제에 실패합니다. 이 경우 애플리케이션은 데이터의 새 인스턴스를 요청한 다음 업데이트/삭제를 다시 시도해야 합니다.

경우에 따라 항목의 다른 변경사항에 관계없이 변경사항을 강제로 적용해야 할 수 있습니다. *If-Match 헤더에 전달하면 됩니다.

If-Match: *

이 설정은 다른 클라이언트의 변경사항을 재정의하므로 주의해서 사용해야 합니다.

강력한 ETag가 있는 항목만 업데이트하거나 삭제할 수 있습니다. 취약한 ETag를 지정하면 오류가 발생합니다. 이 문제를 방지하기 위해 자바스크립트 클라이언트는 업데이트 및 삭제 요청에 취약한 ETag를 설정하지 않습니다.

ETag는 조건부 검색과 동일한 방식으로 사용됩니다.

function updateData(entry, service) {
  var etag = entry.getEtag();
  var opt_params = {};
  opt_params['etag'] = etag; // Or use '*' to force an update.
  service.updateEntry(successHandler, errorHandler, opt_params);
}

function successHandler(response) {
  // Successful update
}

function errorHandler(errorObj) {
  // ERROR - Update failed. Could be due to an ETag mismatch, but check the
  // error message to make sure. An ETag error will be in the format:
  // Mismatch: etags = ["Qnc-fTVSLyp7ImA9WxJbFEsDRAw."], version = [1249675665358000]
}

업데이트할 때 다음 두 위치에서 ETag를 지정할 수 있습니다.

  1. 항목 자체에서 getEtag()setEtag() 메서드를 사용합니다.
  2. 헤더에서 opt_params 객체 사용 (위에서 설명)

이전 GET 요청에서 로드된 항목에는 이미 ETag 필드가 설정되어 있습니다. 따라서 opt_params 객체에서 동일한 ETag를 지정하는 것은 중복입니다. 항목 본문과 opt_params에 모두 ETag가 지정된 경우 opt_params의 ETag가 우선합니다. 이로 인해 약간 혼란스러울 수 있으므로 조건부 업데이트에 문제가 있는 경우 항목 및 opt_params 객체 모두에서 ETag를 확인해야 합니다.

작업을 쉽게 하기 위해 google.gdata.Entry 클래스에는 자체 updateEntry()deleteEntry() 메서드도 있습니다. 항목 클래스에 이미 ETag가 있는 경우 요청에 ETag를 추가할 필요가 없습니다. 클라이언트 라이브러리에서 ETag를 자동으로 추가합니다. 예를 들면 다음과 같습니다.

// entry was loaded from a previous request.  No need to specify
// an ETag in opt_params here, it is added automatically.
entry.deleteEntry(successHandler, errorHandler);

이렇게 하면 ETag를 올바르게 설정할지 걱정할 필요가 없습니다. 그러나 '*'를 사용하여 업데이트를 강제 적용하려는 경우 항상 'etag' = '*'opt_params 객체를 포함해야 합니다.

주소록의 조건부 업데이트에서 직장에서 조건부 업데이트를 확인할 수 있습니다. 샘플은 먼저 이 샘플에서 사용하는 모든 데이터를 만들 테스트 연락처 그룹을 만듭니다. 샘플 사용을 마치면 언제든지 이 연락처 그룹을 삭제할 수 있습니다. 그런 다음 연락처 그룹의 콘텐츠와 함께 두 개의 iframe을 로드합니다. 한 iframe에서 업데이트를 수행하면 다른 iframe의 업데이트에 어떤 영향을 미치는지 확인할 수 있습니다. 사용 방법에 관한 자세한 내용은 샘플을 참고하세요.

샘플

  • Blogger에서 조건부 검색 - 5초마다 Blogger를 폴링하고 업데이트를 확인합니다.
  • 연락처의 조건부 업데이트 - 연락처 데이터가 포함된 두 개의 별도 iframe을 표시하므로 연락처를 생성, 업데이트, 삭제할 때 두 클라이언트가 상호작용하는 방식을 다시 만들 수 있습니다.

참조

클라이언트 라이브러리에서 제공하는 클래스 및 메서드에 대한 자세한 내용은 자바스크립트 클라이언트 라이브러리 API 참조(JSdoc 형식)를 참고하세요.

맨 위로