Google APIs Discovery Service を使用すると、Google API で使用するさまざまなツールを構築できます。ただし、ディスカバリ ドキュメントの主な目的は、Google がさまざまなプログラミング言語でクライアント ライブラリを作成できるようにすることです。このドキュメントでは、Google API にカスタム クライアント ライブラリを作成する方法について説明します。
安定していて機能が完全なクライアント ライブラリは複雑なツールで、開発に数か月かかります。ただし、Google API のシンプルなクライアント ライブラリを構築するための手順は、次の 3 つの簡単なステップにまとめることができます。
ディスカバリ ドキュメントを取得して API サーフェスを構築する
リクエストを作成する
呼び出しを行ってレスポンスを取得する
手順については、以降のセクションで詳しく説明します。また、「例」セクションのシンプルな API クライアントのサンプルでは、これらの手順とコードがどのように対応しているかを確認することもできます。
最初の開発タスクは、ディスカバリ ドキュメントの取得です。ドキュメントを取得する正確なタイミングに関する戦略は、特定した要件によって決まります。たとえば、静的型言語では、プロセスの早い段階でディスカバリ ドキュメントを取得し、そのドキュメントに記述されている特定の API の処理コードを生成します。厳密な型付けを行う言語の場合は、コードを生成し、コンパイル済みのライブラリを構築します。動的型言語の場合、プログラミング構造の構築を遅らせて、プログラミング サーフェスが使用されるときに API とのインターフェースを構築できます。
ディスカバリ ドキュメントの最上位から servicePath を取得します。たとえば、Service Usage API のディスカバリ ドキュメントの servicePath プロパティは空です。
これらを連結すると、次のようになります。
https://serviceusage.googleapis.com/
path プロパティを取得し、URI テンプレートとして展開して、その結果を前のステップの URI と結合します。たとえば、v1 Service Usage API の serviceusage.services.enable メソッドでは、path プロパティの値は v1/{+name}:enable です。したがって、このメソッドの完全な URI は次のようになります。
importhttplib2importjsonimporturitemplateimporturllib# Step 1: Fetch Discovery documentDISCOVERY_URI="https://serviceusage.googleapis.com/$discovery/rest?version=v1"h=httplib2.Http()resp,content=h.request(DISCOVERY_URI)discovery=json.loads(content)location=None# Set this to your location if appropriateuse_global_endpoint=True# Set this to False if you want to target the endpoint for your location# Step 2.a: Construct base URIBASE_URL=Noneifnotuse_global_endpointandlocation:ifdiscovery['endpoints']:BASE_URL=next((item['endpointUrl']foritemindiscovery['endpoints']ifitem['location']==location),None)ifnotBASE_URL:BASE_URL=discovery['rootUrl']BASE_URL+=discovery['servicePath']classCollection(object):passdefcreateNewMethod(name,method):# Step 2.b Compose requestdefnewMethod(**kwargs):body=kwargs.pop('body',None)url=urllib.parse.urljoin(BASE_URL,uritemplate.expand(method['path'],kwargs))forpname,pconfiginmethod.get('parameters',{}).items():ifpconfig['location']=='path'andpnameinkwargs:delkwargs[pname]ifkwargs:url=url+'?'+urllib.parse.urlencode(kwargs)returnh.request(url,method=method['httpMethod'],body=body,headers={'content-type':'application/json'})returnnewMethod# Step 3.a: Build client surfacedefbuild(discovery,collection):forname,resourceindiscovery.get('resources',{}).items():setattr(collection,name,build(resource,Collection()))forname,methodindiscovery.get('methods',{}).items():setattr(collection,name,createNewMethod(name,method))returncollection# Step 3.b: Use the clientservice=build(discovery,Collection())print(serviceusage.services.enable(name='projects/my-project/services/compute.googleapis.com'))
クライアントの重要なコンポーネントは次のとおりです。
ステップ 1: ディスカバリ ドキュメントを取得する。Service Usage API のディスカバリ ドキュメントが取得され、解析されてデータ構造に変換されます。Python は動的型付き言語であるため、ディスカバリ ドキュメントの実行時に取得できます。
ステップ 3.b: クライアントを使用する。構築された API サーフェスがどのように使用されるかを示します。まず、ディスカバリ ドキュメントからサービス オブジェクトが構築され、次に Service Usage API を使用してプロジェクト my-project で Compute Engine API が有効になります。
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["わかりにくい","hardToUnderstand","thumb-down"],["情報またはサンプルコードが不正確","incorrectInformationOrSampleCode","thumb-down"],["必要な情報 / サンプルがない","missingTheInformationSamplesINeed","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-07-29 UTC。"],[[["\u003cp\u003eThe Google APIs Discovery Service allows developers to build custom client libraries for Google APIs, with the primary purpose of facilitating the creation of client libraries in various programming languages.\u003c/p\u003e\n"],["\u003cp\u003eBuilding a client library involves three main steps: fetching the Discovery document to construct the API surface, composing a request including its body and URL, and making the API call to fetch the response.\u003c/p\u003e\n"],["\u003cp\u003eFetching the Discovery document's timing is influenced by the programming language's type system, whether statically-typed languages benefit from early fetching and code generation, while dynamically typed languages can fetch and adapt at runtime.\u003c/p\u003e\n"],["\u003cp\u003eComposing a request involves creating the request body and constructing the request URL, where the URL's path is built using URI Template v04 syntax, incorporating variables from the Discovery document's parameters section.\u003c/p\u003e\n"],["\u003cp\u003eThe client library, after sending a request, must deserialize the response and handle potential error conditions, including HTTP transport issues and error messages following the Google JSON Style Guide.\u003c/p\u003e\n"]]],[],null,["# Build a client library\n\nYou can use the Google APIs Discovery Service for building a variety of different tools to use with Google APIs.\nHowever, the primary purpose of the Discovery document is to allow Google to create client\nlibraries in various programming languages. This document describes how you could go about\nbuilding a custom client library for Google APIs.\n\n\nA stable and feature-complete client library is a complicated tool that can take months to\ndevelop. However, the general instructions for building a simple client library for Google\nAPIs can be broken down to three simple steps:\n\n1. Fetching the Discovery document and constructing API surface\n2. Composing a request\n3. Making a call and fetching the response\n\n\nThese steps are described in more detail in the following sections. You can also have a look\nat the [Simple APIs client](#simple_apis_client) sample in the Examples section to see how\nthese instructions map to the code.\n\nFetch the Discovery document\n----------------------------\n\n\nBefore you begin implementing a client library, there are some basic requirements that impact\nhow you will proceed down your development path. For example, your programming language of\nchoice may be either typed or untyped; if it is typed it could be either statically or\ndynamically typed. It may be compiled or interpreted. These requirements will guide your\napproach to consuming and using the Discovery document.\n\n\nThe first development task is to fetch the Discovery document. Your strategy for exactly when\nthe document is to be fetched is determined by the requirements you identified. For example,\nin a statically-typed language, you might fetch the Discovery document early in the process\nand then generate code to handle the specific API described by the Discovery document. For a\nstrongly-typed language, you might generate some code and build a compiled library. For a\ndynamically typed language, you can lazily construct the programming structures to interface\nto the API on the fly as the programming surface is used.\n\nCompose a request\n-----------------\n\nComposing a requests involves two separate steps:\n\n1. Composing the request body.\n2. Constructing the request URL.\n\n\nYou need to convert the request body, if any, from a language-appropriate\nrepresentation into the correct wire format. For example, in a Java client\nlibrary, there may be a class for each request type that allows type-safe\nmanipulation of the request data and is serializable into JSON.\n\n\nThe construction of the request URL is a slightly more complicated process.\n\n\nThe `path` property of each method in the API uses [URI Template v04](https://code.google.com/p/uri-templates/) syntax. This property may\ncontain variables, which are surrounded by curly braces. Here is an example of a\n`path` property with variables: \n\n```\n/example/path/var\n```\n\n\nIn the path above, `var` is a variable. The value for this variable comes from the\nDiscovery document's `parameters` section for that method. Each variable name has\na corresponding value in the `parameters` object. In the example above, there is a\nparameter named `var` in the `parameters` section (and its\n`location` property is `path`, to indicate that it is a path\nvariable).\n\n\nWhen making a request, you should substitute the value for `var` into the URL.\nFor example, if the user of the library makes a choice that sets `var` to the\nvalue `foo`, the new URL will be `/example/path/foo`.\n\n\nAlso note that the `path` property is a relative URI. In order to calculate the\nabsolute URI, follow these steps:\n\n1. If you know your location (region), and the Discovery document has the `endpoints` property, check if your location is present in the `endpoints` list. If so, grab the `endpointUrl` from the `endpoints` list whose `location` matches yours.\n2.\n If there is no `endpoints` property in the Discovery document or your location\n is not present in the `endpoints` list or you want to target the global\n endpoint, grab the `rootUrl` property from the top level of the\n Discovery document.\n\n\n For example, the `rootUrl` property in the\n [Discovery document](https://serviceusage.googleapis.com/$discovery/rest?version=v1) for\n [the Service Usage API](https://cloud.google.com/service-usage/docs/reference/rest) is: \n\n ```\n https://serviceusage.googleapis.com/\n ```\n3. Grab the `servicePath` from the top level of the Discovery document. For example, the `servicePath` property in the Discovery document for the Service Usage API is empty.\n4. Concatenate them together to get:\n\n ```\n https://serviceusage.googleapis.com/\n ```\n5.\n Grab the `path` property, expand it as a URI Template, and combine the results\n of that expansion with the URI from the previous step. For example, in the v1 Service\n Usage API's `serviceusage.services.enable` method, the value of the\n `path` property is `v1/{+name}:enable`. So, the full URI for the\n method is:\n\n ```\n https://serviceusage.googleapis.com/v1/{+name}:enable\n ```\n\n\nYou don't need an [API key](https://cloud.google.com/docs/authentication/api-keys)\nto call the Service Usage API. However, if the API you're calling requires an API key, you can\nadd the API key to the URI's query string: \n\n```\nREQUEST_URI?key=API_KEY\n```\n\nMake a call and handle the response\n-----------------------------------\n\n\nAfter you send the request, the you need to deserialize the response into the appropriate\nlanguage representation, taking care to handle error conditions that could occur---both in the\nunderlying HTTP transport and error messages generated from the API service. The format of the\nerrors is documented as part of the [Google JSON Style\nGuide](https://google.github.io/styleguide/jsoncstyleguide.xml#error).\n\nExamples\n--------\n\n\nThe following section gives a simple example of an APIs client library.\n\n### Simple APIs client\n\n\nBelow is an example of a very simple client library written in Python3. The client builds an\ninterface for interacting with the [Service Usage API](https://cloud.google.com/service-usage/docs/reference/rest), then\nuses that interface to enable the Compute Engine API (`compute.googleapis.com`) in\nthe project `my-project`.\n**Warning:** The code below is a significantly simplified version of a typical client library. It is an incomplete implementation that is provided to demonstrate some aspects of building a client library. It is not production-ready code. \n\n```python\nimport httplib2\nimport json\nimport uritemplate\nimport urllib\n\n# Step 1: Fetch Discovery document\nDISCOVERY_URI = \"https://serviceusage.googleapis.com/$discovery/rest?version=v1\"\nh = httplib2.Http()\nresp, content = h.request(DISCOVERY_URI)\ndiscovery = json.loads(content)\nlocation = None # Set this to your location if appropriate\nuse_global_endpoint = True # Set this to False if you want to target the endpoint for your location\n\n# Step 2.a: Construct base URI\nBASE_URL = None\nif not use_global_endpoint and location:\n if discovery['endpoints']:\n BASE_URL = next((item['endpointUrl'] for item in discovery['endpoints'] if item['location'] == location), None)\nif not BASE_URL:\n BASE_URL = discovery['rootUrl']\nBASE_URL += discovery['servicePath']\n\nclass Collection(object): pass\n\ndef createNewMethod(name, method):\n # Step 2.b Compose request\n def newMethod(**kwargs):\n body = kwargs.pop('body', None)\n url = urllib.parse.urljoin(BASE_URL, uritemplate.expand(method['path'], kwargs))\n for pname, pconfig in method.get('parameters', {}).items():\n if pconfig['location'] == 'path' and pname in kwargs:\n del kwargs[pname]\n if kwargs:\n url = url + '?' + urllib.parse.urlencode(kwargs)\n return h.request(url, method=method['httpMethod'], body=body,\n headers={'content-type': 'application/json'})\n\n return newMethod\n\n# Step 3.a: Build client surface\ndef build(discovery, collection):\n for name, resource in discovery.get('resources', {}).items():\n setattr(collection, name, build(resource, Collection()))\n for name, method in discovery.get('methods', {}).items():\n setattr(collection, name, createNewMethod(name, method))\n return collection\n\n# Step 3.b: Use the client\nservice = build(discovery, Collection())\nprint (serviceusage.services.enable(name='projects/my-project/services/compute.googleapis.com'))\n```\n\nThe critical components of the client are:\n\n- **Step 1: Fetch the Discovery document**. The Discovery document for the Service Usage API is retrieved and parsed into a data structure. Since Python is a dynamically typed language, the Discovery document can be fetched at runtime.\n- **Step 2.a: Construct the base URI**. The base URI is calculated.\n- **Step 2.b: Compose the request** . When a method is called on a collection the URI Template is expanded with the parameters passed into the method, and parameters with a location of `query` are put into the query parameters of the URL. Finally a request is sent to the composed URL using the HTTP method specified in the Discovery document.\n- **Step 3.a: Build the client surface** . The client surface is built by recursively descending over the parsed Discovery document. For each method in the `methods` section a new method is attached to the `Collection` object. Because collections can be nested we look for `resources` and recursively build a `Collection` object for all of its members if one is found. Each nested collection is also attached as an attribute to the `Collection` object.\n- **Step 3.b: Use the client** . This demonstrates how the built API surface is used. First a service object is built from the Discovery document, then the Service Usage API is used to enable the Compute Engine API in the project `my-project`."]]