arrow_back

Publishing APIs with Apigee X

Join Sign in
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

Publishing APIs with Apigee X

Lab 1 hour 30 minutes universal_currency_alt 5 Credits show_chart Intermediate
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

GSP843

Google Cloud self-paced labs logo

Overview

APIs are designed to be consumed by app developers, who leverage APIs to provide unique experiences for their users. Google Cloud's Apigee API Platform can be used to publish APIs and make them available for app developers to consume.

In this lab, you create an Apigee API proxy, which requires API key verification to restrict access to the API.

You create API products to provide different levels of service for internal and external application developers. You use a Quota policy to limit the number of calls for each specific application. You create a CORS policy to add Cross-Origin Resource Sharing functionality to the API, which allows it to be called from web applications. You then create a developer portal and publish the API products for app developers to consume.

What you'll learn

In this lab, you learn how to perform the following tasks:

  • Verify an API key to restrict access to an API and track application usage
  • Create API products to provide different levels of access for different types of app developers
  • Use the Quota policy to limit the number of calls for a particular application based on attached API product
  • Add Cross-Origin Resource Sharing (CORS) functionality to an API to allow cross-origin API calls from web applications
  • Create a developer portal and publish the API products

Setup and requirements

Before you click the Start Lab button

Read these instructions. Labs are timed and you cannot pause them. The timer, which starts when you click Start Lab, shows how long Google Cloud resources will be made available to you.

This hands-on lab lets you do the lab activities yourself in a real cloud environment, not in a simulation or demo environment. It does so by giving you new, temporary credentials that you use to sign in and access Google Cloud for the duration of the lab.

To complete this lab, you need:

  • Access to a standard internet browser (Chrome browser recommended).
Note: Use an Incognito or private browser window to run this lab. This prevents any conflicts between your personal account and the Student account, which may cause extra charges incurred to your personal account.
  • Time to complete the lab---remember, once you start, you cannot pause a lab.
Note: If you already have your own personal Google Cloud account or project, do not use it for this lab to avoid extra charges to your account.

How to start your lab and sign in to the Google Cloud console

  1. Click the Start Lab button. If you need to pay for the lab, a pop-up opens for you to select your payment method. On the left is the Lab Details panel with the following:

    • The Open Google Cloud console button
    • Time remaining
    • The temporary credentials that you must use for this lab
    • Other information, if needed, to step through this lab
  2. Click Open Google Cloud console (or right-click and select Open Link in Incognito Window if you are running the Chrome browser).

    The lab spins up resources, and then opens another tab that shows the Sign in page.

    Tip: Arrange the tabs in separate windows, side-by-side.

    Note: If you see the Choose an account dialog, click Use Another Account.
  3. If necessary, copy the Username below and paste it into the Sign in dialog.

    {{{user_0.username | "Username"}}}

    You can also find the Username in the Lab Details panel.

  4. Click Next.

  5. Copy the Password below and paste it into the Welcome dialog.

    {{{user_0.password | "Password"}}}

    You can also find the Password in the Lab Details panel.

  6. Click Next.

    Important: You must use the credentials the lab provides you. Do not use your Google Cloud account credentials. Note: Using your own Google Cloud account for this lab may incur extra charges.
  7. Click through the subsequent pages:

    • Accept the terms and conditions.
    • Do not add recovery options or two-factor authentication (because this is a temporary account).
    • Do not sign up for free trials.

After a few moments, the Google Cloud console opens in this tab.

Note: To view a menu with a list of Google Cloud products and services, click the Navigation menu at the top-left. Navigation menu icon

Activate Cloud Shell

Cloud Shell is a virtual machine that is loaded with development tools. It offers a persistent 5GB home directory and runs on the Google Cloud. Cloud Shell provides command-line access to your Google Cloud resources.

  1. Click Activate Cloud Shell Activate Cloud Shell icon at the top of the Google Cloud console.

When you are connected, you are already authenticated, and the project is set to your Project_ID, . The output contains a line that declares the Project_ID for this session:

Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}

gcloud is the command-line tool for Google Cloud. It comes pre-installed on Cloud Shell and supports tab-completion.

  1. (Optional) You can list the active account name with this command:
gcloud auth list
  1. Click Authorize.

Output:

ACTIVE: * ACCOUNT: {{{user_0.username | "ACCOUNT"}}} To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (Optional) You can list the project ID with this command:
gcloud config list project

Output:

[core] project = {{{project_0.project_id | "PROJECT_ID"}}} Note: For full documentation of gcloud, in Google Cloud, refer to the gcloud CLI overview guide.

Open the Apigee UI

The Apigee UI is accessed on a page separate from the Google Cloud Console. This lab has automatically created an Apigee organization that has the same name as the Google Cloud project.

  • Click to open the Apigee UI.

    You may also open the Apigee UI from the Google Cloud Console by opening the Navigation menu (Navigation menu) and selecting Apigee API Management > Apigee.

If you see an error indicating that the project does not have an organization provisioned, the tab might be trying to load the organization for a previous lab.

If you get this error:

  • Click on the organization dropdown.

    Not provisioned error message

    The organization dropdown should show an organization that has the same name as the Google Cloud project.

    Apigee UI organization dropdown

    The organizations listed are those that are accessible by the logged-in user. For this lab, you should be logged in with the lab credentials provided in the Lab Details panel when you started the lab.

    You can navigate the Apigee UI using its left navigation menu. The landing page also shows quick links for navigating to commonly used locations.

Task 1. Proxy the backend service with an Apigee API proxy

In this task, you create an Apigee API proxy that acts as a facade for a backend service. The API proxy will use a service account to allow it to present OpenID Connect identity tokens to the Cloud Run service.

A backend service named simplebank-rest has already been created and deployed to Cloud Run.

Create the Apigee proxy

  1. In Cloud Shell, to retrieve the URL for the backend service, use the following command:
gcloud run services describe simplebank-rest --platform managed --region {{{project_0.default_region |REGION}}} --format 'value(status.url)'

Save this URL. It will be used when creating the API proxy.

  1. Select the Apigee UI tab in your browser window.

  2. On the left navigation menu, select Develop > API Proxies.

  3. To create a new proxy using the proxy wizard, click Create New.

    You will create a reverse proxy for your backend service.

  4. Click the Reverse proxy box.

Note: Do not click the "Use OpenAPI Spec" link within the reverse proxy box.
  1. Specify the following for the Proxy details:

    Property Value
    Name bank-v1
    Base path /bank/v1
    Target (Existing API) backend URL
    Note: Confirm that you are using "/bank/v1" for the base path, not "/bank-v1".

    The target should be the backend URL you retrieved earlier in the task, which should look something like this:

    https://simplebank-rest-mtdtzt7yzq-ue.a.run.app
  2. Click Next.

  3. Leave the Common Policies settings at their defaults, and click Next.

  4. On the summary page, leave the settings at their defaults, and click Create.

  5. Click Edit proxy.

  6. If a Switch to Classic link is in the upper right corner, click that link.

Task 2. Add a VerifyAPIKey policy

In this task, you add a VerifyAPIKey policy to the API proxy. Any request which does not provide a valid API key will be rejected.

A VerifyAPIKey policy enforces verification of API keys at runtime, letting only applications with approved API keys to access the API. The policy ensures that the API key is valid, has not been revoked, and is approved to consume the specific resource that is being requested.

Add the VerifyAPIKey policy

  1. Click the Develop tab.

  2. In the Navigator menu for the proxy, in the Proxy Endpoints section, click PreFlow.

    The VerifyAPIKey policy should be placed very early on in the API proxy. The request PreFlow in the default proxy endpoint is the first flow that is executed when a request comes in to the API proxy.

  3. In the Flow pane, click the +Step button in the upper right above the request flow.

  4. In the Security section, select Verify API Key, and then set the Display Name and Name to VAK-VerifyKey.

  5. Click Add.

    The VerifyAPIKey configuration is shown in the Code pane.

    The APIKey element indicates where the API key is provided in the request.

  6. In the APIKey element, replace request.queryparam.apikey with request.header.apikey.

    An API key is less likely to be logged or saved in browser history if it is specified in a header.

Modify the target to send an OpenID Connect identity token

The backend service is deployed to require authenticated access, so you cannot call the service without a valid OpenID Connect identity token.

The HTTPTargetConnection specifies the backend target for the service.

  1. In the Navigator menu for the proxy, in the Target Endpoints section, click PreFlow.

  2. Find the following code (your URL will be different):

    <HTTPTargetConnection> <URL>https://simplebank-rest-zce6j3rjwq-uw.a.run.app</URL> </HTTPTargetConnection>
Note: If you do not see the HTTPTargetConnection section, make sure you have clicked on the PreFlow in the Target Endpoints section, not in the Proxy Endpoints section.
  1. Below the URL, add an Authentication section that looks like this:
<Authentication> <GoogleIDToken> <Audience>AUDIENCE</Audience> </GoogleIDToken> </Authentication>
  1. Replace AUDIENCE with the URL value already in the HTTPTargetConnection section. Your code should now look similar to this, except with your specific URL in the URL and Audience elements:
<TargetEndpoint name="default"> <PreFlow name="PreFlow"> <Request/> <Response/> </PreFlow> <Flows/> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <HTTPTargetConnection> <URL>https://simplebank-rest-zce6j3rjwq-uw.a.run.app</URL> <Authentication> <GoogleIDToken> <Audience>https://simplebank-rest-zce6j3rjwq-uw.a.run.app</Audience> </GoogleIDToken> </Authentication> </HTTPTargetConnection> </TargetEndpoint>
  1. Click Save.

Confirm that the runtime instance is available

  1. In Cloud Shell, paste and run the following set of commands:

    export INSTANCE_NAME=eval-instance; export ENV_NAME=eval; export PREV_INSTANCE_STATE=; echo "waiting for runtime instance ${INSTANCE_NAME} to be active"; while : ; do export INSTANCE_STATE=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${GOOGLE_CLOUD_PROJECT}/instances/${INSTANCE_NAME}" | jq "select(.state != null) | .state" --raw-output); [[ "${INSTANCE_STATE}" == "${PREV_INSTANCE_STATE}" ]] || (echo; echo "INSTANCE_STATE=${INSTANCE_STATE}"); export PREV_INSTANCE_STATE=${INSTANCE_STATE}; [[ "${INSTANCE_STATE}" != "ACTIVE" ]] || break; echo -n "."; sleep 5; done; echo; echo "instance created, waiting for environment ${ENV_NAME} to be attached to instance"; while : ; do export ATTACHMENT_DONE=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${GOOGLE_CLOUD_PROJECT}/instances/${INSTANCE_NAME}/attachments" | jq "select(.attachments != null) | .attachments[] | select(.environment == \"${ENV_NAME}\") | .environment" --join-output); [[ "${ATTACHMENT_DONE}" != "${ENV_NAME}" ]] || break; echo -n "."; sleep 5; done; echo "***ORG IS READY TO USE***";

    This series of commands uses the Apigee API to determine when the Apigee runtime instance has been created and the eval environment has been attached.

  2. Wait until the instance is ready.

    When the text ***ORG IS READY TO USE*** is displayed, the instance is ready. The Apigee organization (org) may have been created before you started the lab, so you might not have to wait for the instance to be created.

    If you are waiting for the org to be ready, you can learn about API products, CORS (cross-origin resource sharing), and developer portals.

Deploy the API proxy

  1. Select the Apigee UI tab in your browser window.

  2. On the left navigation menu, select Develop > API Proxies, and then click bank-v1.

  3. Click the Develop tab.

  4. Click Deploy to eval.

    A dialog asks you to confirm the deployment.

  5. For Service Account, specify the service account's email address:

    apigee-internal-access@{{{ project_0.project_id | PROJECT }}}.iam.gserviceaccount.com
  6. Click Deploy.

  7. Click the Overview tab, and wait for the eval deployment status to show that the proxy has been deployed.

Click Check my progress to verify the objective. Create the API proxy

Test the API proxy

The eval environment in the Apigee organization can be called using the hostname eval.example.com. The DNS entry for this hostname has been created within your project, and it resolves to the IP address of the Apigee runtime instance. This DNS entry has been created in a private zone, which means it is only visible on the internal network.

Cloud Shell does not reside on the internal network, so Cloud Shell commands cannot resolve this DNS entry. A virtual machine (VM) within your organization can access the private zone DNS. A virtual machine named apigeex-test-vm was automatically created. You can use this machine to call the API proxy.

  1. In Cloud Shell, open an SSH connection to your test VM:

    TEST_VM_ZONE=$(gcloud compute instances list --filter="name=('apigeex-test-vm')" --format "value(zone)") gcloud compute ssh apigeex-test-vm --zone=${TEST_VM_ZONE} --force-key-file-overwrite
  2. If asked to authorize, click Authorize.

  3. For each question asked in the Cloud Shell, click Enter or Return to specify the default input.

    Your logged in identity is the owner of the project, so SSH to this machine is allowed.

    Your Cloud Shell session is now running inside the VM.

  4. Call the deployed bank-v1 API proxy in the eval environment:

    curl -i -k -X GET "https://eval.example.com/bank/v1/customers"

    The -k option tells curl to skip verification of the TLS certificate. For this lab, the Apigee runtime is using a self-signed certificate instead of a certificate that has been created by a trusted certificate authority (CA).

    Note: You should not use the -k option to bypass certificate verification for production use cases.

    This API attempts to retrieve a list of customers. You should now see a 401 Unauthorized response similar to this:

    HTTP/2 401 content-type: application/json x-request-id: 01e8da87-dc8c-4428-9cdf-8bea84e98860 content-length: 146 date: Tue, 07 Dec 2021 22:54:37 GMT via: 1.1 google {"fault":{"faultstring":"Failed to resolve API Key variable request.header.apikey","detail":{"errorcode":"steps.oauth.v2.FailedToResolveAPIKey"}}}

    This response indicates that the API proxy has blocked access to the backend service because the API key was not provided.

  5. Enter the command exit to leave the SSH session and return to Cloud Shell.

Task 3. Add API products and an application

In this task, you add API products that will provide different levels of access for your API. You will then create two applications and associate separate API products for them, providing them with different access.

Create the first API product

The first API product provides full access to the service.

  1. Select the Apigee UI tab in your browser window.

  2. On the left navigation menu, select Publish > API Products.

  3. To create a new API product, click +Create.

  4. In the Product details pane, specify the following:

    Property Value
    Name bank-fullaccess
    Display Name bank (full access)
    Description allows full access to bank API
    Environment select eval
    Access select Public

    Leave Automatically approve access requests selected.

  5. In the Operations section, click +Add an Operation.

    Operations are used to specify which requests in which API proxies are allowed for an application associated with the API product.

    Note: Confirm that the button is in the "Operations" section, not the "GraphQL Operations" section.
  6. Specify the following:

    Property Value
    Source select the bank-v1 API proxy
    Path /**
    Methods select GET, PATCH, POST, PUT, and DELETE

    The path expression "/**" indicates that any path suffix of any depth is a match for the operation.

    In a production environment, you might choose to add each operation that is allowed separately, rather than using this wildcard path expression.

  7. Click Save to save the operation.

  8. In the Custom Attributes section for the API product, click +Add Custom Attribute.

    Custom attributes can be used to attach any data that you would like to be available in the proxy to control access.

    In this case, because this is the full access API product for your retail API, you'll create a custom attribute that indicates that the application calling the API should be allowed full access.

  9. Specify the following:

    Property Value
    Name full-access
    Value yes
  10. Click OK to save the custom attribute.

  11. To save the API product, click Save at the top of the page.

  12. Return to the Publish > API Products page. The API product will be listed.

Click Check my progress to verify the objective. Create the full access API product

Create an API product providing limited access

The second API product will provide read-only access to the service.

  1. To create a new API product, click +Create.

  2. In the Product details pane, specify the following:

    Property Value
    Name bank-readonly
    Display Name bank (read-only)
    Description allows read-only access to bank API
    Environment select eval
    Access select Public

    Leave Automatically approve access requests selected.

  3. In the Operations section, click +Add an Operation.

    Note: Confirm that the button is in the "Operations" section, not the "GraphQL Operations" section.
  4. Specify the following:

    Property Value
    Source select the bank-v1 API proxy
    Path /**
    Methods select GET
  5. Click Save to save the operation.

  6. To save the API product, click Save at the top of the page.

  7. Return to the Publish > API Products page. The API product will be listed.

Create an app developer

Before creating an app, you must create an app developer.

Note: App developers are typically created using a developer portal, and you will be creating your developer portal later in the lab. For now, use the Apigee console to create the developer.
  1. On the left navigation menu, click Publish > Developers.

  2. To create a new app developer, click +Developer.

  3. Specify the following:

    Property Value
    First Name Joe
    Last Name Developer
    Username joe
    Email joe@example.com
  4. Click Create to create the app developer.

Create an app with read-only access

  1. On the left navigation menu, click Publish > Apps.

  2. To create a new app, click +App.

  3. In the App details pane, specify the following:

    Property Value
    Name readonly-app
    Developer select joe@example.com
  4. In the Credentials pane, click Add product, click on bank (read-only), and then click Add(1) to add.

    Status should already be marked as approved.

  5. Click Create in the upper right corner to create the app.

    The Key and Secret are now configured for the app.

  6. Click on Show next to Key.

    This is the API key which will be used to call the API. You could copy the key, but the next steps will use a curl call to the Apigee API to retrieve the API key.

Create an app with full access

  1. On the left navigation menu, click Publish > Apps.

  2. To create a new app, click +App.

  3. In the App details pane, specify the following:

    Property Value
    Name fullaccess-app
    Developer select joe@example.com
  4. In the Credentials pane, click Add product, click on bank (full access), and then click Add(1) to add.

    Status should already be marked as approved.

  5. Click Create in the upper right corner to create the app.

Click Check my progress to verify the objective. Create the read-only API product, app developer, and 2 apps

Test with the API key

  1. In Cloud Shell, open an SSH connection to your test VM:

    TEST_VM_ZONE=$(gcloud compute instances list --filter="name=('apigeex-test-vm')" --format "value(zone)") gcloud compute ssh apigeex-test-vm --zone=${TEST_VM_ZONE} --force-key-file-overwrite
  2. If asked to authorize, click Authorize.

    Your Cloud Shell session is now running inside the VM.

  3. To get the API key for the read-only application, run the following commands:

    export PROJECT_ID=$(gcloud config list --format 'value(core.project)' 2>/dev/null) echo "PROJECT_ID=${PROJECT_ID}" export API_KEY=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${PROJECT_ID}/developers/joe@example.com/apps/readonly-app" | jq ".credentials[0].consumerKey" --raw-output) echo "API_KEY=${API_KEY}"

    The first command reads the gcloud configuration to get the current project. The second command retrieves the API key using the Apigee API. The request is authorized because you send an access token that has the permissions of the logged in user.

  4. Call the deployed bank-v1 API proxy in the eval environment, using a fake API key:

    curl -i -k -X GET -H "apikey: ABC123" "https://eval.example.com/bank/v1/customers"

    The response is 401 Unauthorized with a fault indicating that the API key was invalid.

  5. Call the deployed bank-v1 API proxy in the eval environment, using the real API key:

    curl -i -k -X GET -H "apikey: ${API_KEY}" "https://eval.example.com/bank/v1/customers"

    The request is allowed, and the response contains a list of customers.

  6. Make another call to the deployed bank-v1 API proxy in the eval environment, again using the real API key:

    curl -i -k -X POST -H "apikey: ${API_KEY}" -H "Content-Type: application/json" "https://eval.example.com/bank/v1/customers" -d '{"firstName": "Julia", "lastName": "Dancey", "email": "julia@example.org"}'

    This time the response is 401 Unauthorized with a fault indicating that the API key is invalid for the given resource. The request was rejected because the supplied API key is associated with the read-only API product, which does not allow POST requests.

  7. Enter exit to exit the virtual machine SSH session.

Task 4. Enforce a quota

In this task, you add a Quota policy that will limit the number of requests that will be allowed per application over a specific period of time. The Quota policy will use a quota configuration that has been specified in the API products.

Add the quota policy

  1. Select the Apigee UI tab in your browser window.

  2. On the left navigation menu, select Develop > API Proxies, and then click bank-v1.

  3. Click the Develop tab.

  4. In the Navigator menu for the proxy, in the Proxy Endpoints section, click PreFlow.

    The Quota policy will verify that the quota for a specific application has not been exceeded. If the limit has been reached, the Quota policy will raise a fault, and the request will be aborted. If the limit has not been reached, the number of allowed requests will be decremented.

    The Quota policy determines the calling application based on a variable populated by the VerifyAPIKey policy. Therefore, the Quota policy must be placed after the VerifyAPIKey policy.

  5. In the Flow pane, click the +Step button in the upper right above the request flow.

  6. In the Traffic Management section, select Quota, and then set the Display Name and Name to Q-EnforceQuota.

  7. Click Add.

    The Quota configuration is shown in the Code pane.

  8. Change the Quota configuration to:

    <Quota continueOnError="false" enabled="true" name="Q-EnforceQuota" type="calendar"> <Identifier ref="client_id"/> <UseQuotaConfigInAPIProduct stepName="VAK-VerifyKey"> <DefaultConfig> <Allow>2</Allow> <Interval>1</Interval> <TimeUnit>hour</TimeUnit> </DefaultConfig> </UseQuotaConfigInAPIProduct> <Distributed>true</Distributed> <Synchronous>true</Synchronous> <StartTime>2021-01-01 00:00:00</StartTime> </Quota>

    You will be using the API product to specify the allowed rate. The stepName in the UseQuotaConfigInAPIProduct element specifies which step will determine the API product.

    When an API key or OAuth token is validated, it can be associated with an app that is associated with an API product. Using these policy settings, the VerifyAPIKey step called VAK-VerifyKey determines the API product. The VerifyAPIKey policy must run before the Q-EnforceQuota policy.

    The default configuration values specified in the Quota policy specify a maximum of 2 (Allow) requests per 1 (Interval) month (TimeUnit). The default values will only be used if the values are not available, which should only happen if the quota settings are not set for the API product associated with the API key.

  9. Click Save. If you are notified that the proxy was saved as a new revision, click OK.

  10. Click Deploy to eval, and then click Deploy.

  11. Click the Overview tab, and wait for the eval deployment status to show that the proxy has been deployed.

Add a quota configuration for the full access API product

  1. On the left navigation menu, select Publish > API Products, and then click bank (full access).
  2. Click Edit.
  3. On the bank-v1 line in the Operations section, click the Actions menu icon (Actions menu) and select Edit.
  4. Set the operation's quota to 5 requests every 1 minute, and click Save to save the operation.
Note: Ensure that you are editing the quota that is configured within the operation.
  1. Click Save to save the API product.

Click Check my progress to verify the objective. Add the quota policy and API product quota configuration

Start a debug session

Debug is a tool for troubleshooting and monitoring API proxies running on Apigee. The Debug tool lets you examine the details of each step during an API call.

  1. On the left navigation menu, select Develop > API Proxies, and then click bank-v1.

  2. Click the Debug tab.

  3. In the Start a debug session pane, on the environment dropdown, select eval.

  4. Click Start Debug Session.

    It may take a short period of time before the debug session starts capturing requests.

Note: If you get error messages in red boxes toward the top of the screen, with descriptions like "Error fetching debug transactions" or "List debug session transaction error," your debug session may still work correctly.

You will make API requests and then examine the debug session.

Test the quota

  1. In Cloud Shell, open an SSH connection to your test VM:

    TEST_VM_ZONE=$(gcloud compute instances list --filter="name=('apigeex-test-vm')" --format "value(zone)") gcloud compute ssh apigeex-test-vm --zone=${TEST_VM_ZONE} --force-key-file-overwrite
  2. If asked to authorize, click Authorize.

Your Cloud Shell session is now running inside the VM.

  1. To get both API keys, run the following commands:

    export PROJECT_ID=$(gcloud config list --format 'value(core.project)' 2>/dev/null) echo "PROJECT_ID=${PROJECT_ID}" export API_KEY_READONLY=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${PROJECT_ID}/developers/joe@example.com/apps/readonly-app" | jq ".credentials[0].consumerKey" --raw-output) echo "API_KEY_READONLY=${API_KEY_READONLY}" export API_KEY_FULL=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${PROJECT_ID}/developers/joe@example.com/apps/fullaccess-app" | jq ".credentials[0].consumerKey" --raw-output) echo "API_KEY_FULL=${API_KEY_FULL}"
  2. Repeatedly send this request until you get a quota failure:

    curl -i -k -X GET -H "apikey: ${API_KEY_READONLY}" "https://eval.example.com/bank/v1/customers" Note: To quickly repeat a command in Cloud Shell or an SSH session, click the UP arrow key and then press RETURN or ENTER.

    Your quota violation will look similar to this:

    {"fault":{"faultstring":"Rate limit quota violation. Quota limit exceeded. Identifier : bKSV3nOz2JS5Z58sWMh2RBnnwWeEeNK2N2G6HMCESgLGDLFI","detail":{"errorcode":"policies.ratelimit.QuotaViolation"}}}
  3. Return to the Apigee UI tab.

    You should see some 200 requests and a 429 request.

    Click on a 200 request. The transaction map shows a factory icon at the right side, indicating that the backend was called.

  4. In the Debug session pane, click the left arrow (<) at the upper left to return to the Start a debug session pane.

  5. Click Start Debug Session to start a new Debug session.

  6. Return to the SSH session, and then repeatedly send this request using the full access API key until you get a quota failure:

    date; curl -i -k -X GET -H "apikey: ${API_KEY_FULL}" "https://eval.example.com/bank/v1/customers"

    This time you should be able to send at least 5 requests before being rejected with a 429 response. The quota for the full access API product is 5 requests per minute. The quota is reset when the seconds part of the time resets to zero. The command above prints the time before calling the API, so you should be able to see the approximate time when the quota is reset.

  7. Enter exit to exit the virtual machine SSH session.

  8. Return to the Apigee UI tab.

    If you select a request and click on the quota icon, you can see that the VAK-VerifyKey quota variables now indicate 5 requests per 1 minute.

Task 5. Add CORS to the API proxy

In this task, you add CORS (cross-origin resource sharing) to the bank-v1 proxy.

CORS is a protocol that uses HTTP headers to indicate to browsers whether it is safe to access restricted resources from a separate domain. By default, cross-domain requests are forbidden by the same-origin security policy. The same-origin policy protects browser users from unknowingly sharing session information with bad actors.

The same-origin policy means that a web page served from www.example.com could not, by default, make a call to APIs at api.example.com because the host name is different. CORS can be used to allow this kind of cross-origin access.

You will need CORS in the bank API for the developer portal. An Apigee developer portal has a domain name of *.apigee.io, and the API is accessed via a different domain. In order to invoke the API from the documentation, you will add CORS headers to all API responses, including error responses.

CORS also uses preflight requests. The browser sends a preflight request using the OPTIONS verb to find out whether the next call will be allowed.

The CORS policy can handle all of the CORS functionality.

For more information about CORS, refer to the Apigee CORS documentation.

Add the CORS policy

  1. On the left navigation menu, select Develop > API Proxies, and then click bank-v1.

  2. Click the Develop tab.

  3. In the Navigator menu for the proxy, in the Proxy Endpoints section, click PreFlow.

  4. In the Flow pane, click the +Step button in the upper right above the request flow.

  5. In the Security section, select CORS, and then set the Display Name and Name to CORS.

  6. Click Add.

    The CORS policy configuration is shown below the Flow pane.

    AllowOrigins lists the allowed origins. The default configuration allows any Origin, because it sets the allowed origin equal to the Origin that is passed in the request. In a typical production use case, you might only allow requests from specific hostnames.

    AllowMethods specifies the methods that should be allowed for the API.

    AllowHeaders lists the headers that may be passed in the request.

    ExposeHeaders specifies the headers in the response that should be allowed when being called with an Origin. With the default value of *, no response headers will be stripped from the response.

    MaxAge specifies how long a preflight response may be cached by a browser, in seconds.

    AllowCredentials indicates whether Authorization headers, TLS client certificates, or cookies can be sent in the request.

    GeneratePreflightResponse specifies whether preflight requests with the OPTIONS method will be handled.

  7. Replace the AllowHeaders configuration with:

    <AllowHeaders>origin, x-requested-with, accept, content-type, apikey</AllowHeaders>

    Your API is using the apikey header to specify an API key, so it must be added so it can be called from a browser.

  8. Replace the MaxAge value with -1.

    This will disable the browser's caching of the preflight response, so that you will always see the preflight request. In a production use case, you will typically allow caching of the response to avoid making two calls per request.

  9. In the Navigator menu for the proxy, in the Proxy Endpoints section, click PreFlow.

    When the CORS policy was added, it was automatically added at the end of the flow. However, for preflight requests, an API key should not be required.

  10. Move the CORS policy before the VAK-VerifyKey policy.

    You can drag the policy to the left using your mouse:

    drag CORS policy

    Alternatively, you can move the policy by editing the PreFlow configuration. Replace:

    <PreFlow name="PreFlow"> <Request> <Step> <Name>VAK-VerifyKey</Name> </Step> <Step> <Name>Q-EnforceQuota</Name> </Step> <Step> <Name>CORS</Name> </Step> </Request> <Response/> </PreFlow>

    with:

    <PreFlow name="PreFlow"> <Request> <Step> <Name>CORS</Name> </Step> <Step> <Name>VAK-VerifyKey</Name> </Step> <Step> <Name>Q-EnforceQuota</Name> </Step> </Request> <Response/> </PreFlow>
  11. Click Save. If you are notified that the proxy was saved as a new revision, click OK.

  12. Click Deploy to eval, and then click Deploy.

  13. Click the Overview tab, and wait for the eval deployment status to show that the proxy has been deployed.

Click Check my progress to verify the objective. Add CORS to the API proxy

Start a debug session

  1. Click the Debug tab

  2. In the Start a debug session pane, on the environment dropdown, select eval.

  3. Click Start Debug Session.

    It may take a short period of time before the debug session starts capturing requests.

Test the CORS functionality

  1. In Cloud Shell, open an SSH connection to your test VM:

    TEST_VM_ZONE=$(gcloud compute instances list --filter="name=('apigeex-test-vm')" --format "value(zone)") gcloud compute ssh apigeex-test-vm --zone=${TEST_VM_ZONE} --force-key-file-overwrite
  2. If asked to authorize, click Authorize.

    Your Cloud Shell session is now running inside the VM.

  3. To get an API key, run the following commands:

    export PROJECT_ID=$(gcloud config list --format 'value(core.project)' 2>/dev/null) echo "PROJECT_ID=${PROJECT_ID}" export API_KEY=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${PROJECT_ID}/developers/joe@example.com/apps/fullaccess-app" | jq ".credentials[0].consumerKey" --raw-output) echo "API_KEY=${API_KEY}"
  4. Make a request to retrieve the list of customers:

    curl -i -k -X GET -H "apikey: ${API_KEY}" "https://eval.example.com/bank/v1/customers"

    There is no Origin, so the CORS functionality is skipped. Confirm that the Access-Control-Allow-Origin header is not returned.

  5. Make another request, but include the Origin header this time. This tests a normal CORS request:

    curl -i -k -X GET -H "Origin: https://www.example.com" -H "apikey: ${API_KEY}" "https://eval.example.com/bank/v1/customers"

    The access-control-* headers are returned because the Origin was supplied.

  6. Make a preflight request:

    curl -i -k -X OPTIONS -H "Origin: https://www.example.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: Content-Type,apikey" "https://eval.example.com/bank/v1/customers"

    The CORS policy sets the preflight headers in the response and blocks the request from continuing through to the backend.

    If you return to the Apigee UI and look at the OPTIONS call in the Debug tool, you can confirm that the CORS policy did not allow the call to pass through to the backend service.

  7. Enter exit to exit the virtual machine SSH session.

Task 6. Download and modify an OpenAPI specification

In this task, you download and modify an OpenAPI specification that defines the interface for your API proxy.

The OpenAPI specification will be used when publishing your API proxy to your developer portal.

Download the OpenAPI specification and edit it

  1. In Cloud Shell, to download the OpenAPI specification for your API proxy, run this command:

    curl https://storage.googleapis.com/cloud-training/api-dev-quest/dev-portal/simplebank-spec.yaml?$(date +%s) --output ~/simplebank-spec.yaml

    This curl command downloads a file named simplebank-spec.yaml and stores it in a file with the same name in the home directory.

Note: "?$(date +%s)" adds a query parameter to the URL that is a string representation of the current date/time. This dynamically changing variable changes the URL and forces curl to retrieve the latest version of a file, even if a previous version is cached.
  1. In Cloud Shell, click Open Editor, and then click Open in new window if necessary.

    cloud shell editor button

  2. In the editor, select the simplebank-spec.yaml file.

    This OpenAPI specification specifies the interface of the API proxy that you have created during this lab. The specification will be used to provide live documentation in the developer portal.

    The developer portal accesses the Apigee proxy from the external network. The hostname you have been using, eval.example.com, is only available on the internal network.

    A load balancer has been provisioned to provide external access to the API proxy. External access uses a hostname provided by nip.io, which is a wildcard DNS provider.

    The external hostname will look similar to this:

    eval.60.70.80.90.nip.io

    This hostname has already been specified as a matching hostname for the eval-group environment group.

  3. In Cloud Shell, to retrieve the eval-group settings, use the following command:

    curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${GOOGLE_CLOUD_PROJECT}/envgroups/eval-group"

    The hostnames array contains two hostnames: one without an IP address (eval.example.com), and one with an IP address (similar to eval.60.70.80.90.nip.io). You will use the hostname with the IP address in the OpenAPI spec.

  4. In the editor, on line 10, replace the hostname:

    eval.<IPADDR>.nip.io

    Once you have replaced the hostname in the server URL, line 10 should look similar to this:

    - url: "https://eval.60.70.80.90.nip.io/bank/v1"
  5. Click File > Save.

  6. Click File > Download.

    This will download the file to your local machine. You will use the updated specification with the developer portal.

Task 7. Create a developer portal and publish an API to it

In this task, you create an integrated developer portal and then publish your API to it.

Create an integrated developer portal

  1. In the Apigee UI, click Publish > Portals.

  2. Click Get started.

  3. Enter bank as the name, and then click Create.

    Creation may take a minute, and then the portal overview page should open.

  4. If a message to "Enroll in beta for team and audience management features" is displayed, click Enroll.

Publish your API to the portal

  1. Click API catalog.

  2. Click +.

  3. Select the bank (full access) product, and then click Next.

  4. Customize the API details:

    Property Value
    Published (listed in the catalog) selected
    Display title SimpleBank
    Display description SimpleBank API v1
    API visibility select Public (visible to anyone)

    Published makes the API visible on the portal, and Public visibility allows APIs to be seen even if the user is not logged in to the portal.

  5. Click Select image and then click the Image URL link.

  6. Set the image URL to:

    https://storage.googleapis.com/cloud-training/api-dev-quest/dev-portal/piggy-bank.png

    You should see the image of a piggy bank.

  7. Click Select.

  8. In the API documentation section, select OpenAPI document.

  9. Click Select Document.

  10. Click on the cloud image to select a file to upload.

  11. Select the OpenAPI spec file you downloaded from Cloud Shell (simplebank-spec.yaml), and then click Open.

  12. Click Select.

  13. Click Save.

  14. To open the developer portal in a new tab, click Live Portal.

Click Check my progress to verify the objective. Create the integrated developer portal

Start a Debug session

  1. Return to the Apigee UI, select Develop > API Proxies, and then click bank-v1.
  2. Click the Debug tab.
  3. In the Start a debug session pane, on the environment dropdown, select eval.
  4. Click Start Debug Session.

Test the API using the developer portal

  1. In Cloud Shell, to get the full access API key, run the following command:

    export PROJECT_ID=$(gcloud config list --format 'value(core.project)' 2>/dev/null) echo "PROJECT_ID=${PROJECT_ID}" export API_KEY=$(curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://apigee.googleapis.com/v1/organizations/${PROJECT_ID}/developers/joe@example.com/apps/fullaccess-app" | jq ".credentials[0].consumerKey" --raw-output) echo "API_KEY=${API_KEY}"

    Copy the API key into the clipboard.

  2. Return to the Live Portal tab, and click APIs.

  3. Click the piggy bank.

    The SimpleBank API is shown.

  4. Click Authorize.

  5. Paste the API key as the Key.

  6. Click Authorize, and then click OK.

    The API key will now be sent with any request.

  7. In the left menu, click /customers POST.

  8. Specify the following request body:

    { "email": "mina@example.com", "lastName": "Yu", "firstName": "Mina" }
  9. Click Execute.

    A 200 OK response indicates that the customer was created.

  10. In the left menu, click /customers GET.

  11. Click Execute.

    The customer you just created is returned with the other customers in the database.

    If you return to the Apigee UI and the Debug session, you can see that an OPTIONS (preflight) request was automatically sent by the browser before sending both commands. A preflight request is required before the GET command, since browser does not know whether the apikey header should be allowed.

Task 8. Create an app developer in the portal (optional)

In this task, you will use the developer portal to create an app developer.

Note: This task requires that you enter your email address to receive a registration email. The email contains a link that must be clicked before the registered account can log in to the developer portal. The email address will not be used for any other purpose, and it will be deleted when the Google Cloud project is automatically deleted.

Register an app developer in the developer portal

  1. Return to the Live Portal, and click Sign In.

  2. Click Create an account.

  3. Enter a first name, last name, email address, and password.

    You will need to use the password to log in to the developer portal, so make it something you can remember.

  4. Click the box indicating that you agree to the terms.

    The Terms and Conditions page would be specified by the organization providing the APIs to app developers.

  5. Click Create Account.

    An email is sent to your email address. It includes a link that must be clicked to allow the account user to log in.

  6. Click the emailed link.

    A browser tab will open to the developer portal.

  7. Click Sign In.

  8. Enter the email address and password, and then click Sign In.

Create an app for the app developer

  1. Click the email address in the upper right corner, and then click Apps.

  2. Click + New App.

  3. Specify MyApp as the App Name.

  4. In the APIs section, for SimpleBank, click Enable.

  5. Click Save.

    The app is registered, and the API key is shown. This API key may be used within the developer portal. The app developer and app can be seen by returning to the Apigee UI and navigating to Publish > Developers and Publish > Apps respectively.

Congratulations!

In this lab, you used API key verification to restrict access to the API. You created API products to provide different levels of service for internal and external app developers. You used a Quota policy to limit the number of calls for each app, and added a CORS policy to support Cross-Origin Resource Sharing in the API. You created a developer portal and published the API products for app developers to consume.

Next steps / Learn more

Google Cloud training and certification

...helps you make the most of Google Cloud technologies. Our classes include technical skills and best practices to help you get up to speed quickly and continue your learning journey. We offer fundamental to advanced level training, with on-demand, live, and virtual options to suit your busy schedule. Certifications help you validate and prove your skill and expertise in Google Cloud technologies.

Manual Last Updated: February 16, 2024

Lab Last Tested: January 29, 2023

Copyright 2024 Google LLC All rights reserved. Google and the Google logo are trademarks of Google LLC. All other company and product names may be trademarks of the respective companies with which they are associated.