Temporary resource names
GoogleAdsService.Mutate
supports
temporary resource names that can be referenced later
on in the same request. This lets you, for example, create a campaign and
its associated ad groups, ads, keywords, etc. all in a single request.
You can do this by specifying the new resource's resource_name
to use a
negative ID. For example, if you create a campaign and specify its resource name
as customers/<YOUR_CUSTOMER_ID>/campaigns/-1
, then when you are creating the
ad group in a later operation, you can reference it by that resource name and
the -1
you specified will be replaced by the actual ID of the created campaign
automatically.
Here are some things to keep in mind when using temporary resource names:
- A temporary resource name can only be used after it's been defined in a resource. In the example below, the ad group operation would have to appear after the campaign operation in the list of operations.
- Temporary resource names are not remembered across jobs or mutate requests; to reference a resource created in a previous job or mutate request, use its actual resource name.
- For a single job or mutate request, each temporary resource name must use a unique negative number, even if they are from different resource types. If a temporary ID is reused in a single job or mutate request, then an error is returned.
Example
To give a more concrete example to the situation mentioned above, suppose you want to add a campaign, an ad group, and an ad in a single API request. You would create a structure for your request analogous to the following:
mutate_operations: [
{
campaign_operation: {
create: {
resource_name: "customers/<YOUR_CUSTOMER_ID>/campaigns/-1",
...
}
}
},
{
ad_group_operation: {
create: {
resource_name: "customers/<YOUR_CUSTOMER_ID>/adGroups/-2",
campaign: "customers/<YOUR_CUSTOMER_ID>/campaigns/-1"
...
}
}
},
{
ad_group_ad_operation: {
create: {
ad_group: "customers/<YOUR_CUSTOMER_ID>/adGroups/-2"
...
}
}
},
]
Notice that a new temporary ID is used for the ad group, since we can't reuse
the -1
that we used for the campaign, and we also reference this ad group when
creating an ad group ad. The ad group itself references the resource name we
established for the campaign in an earlier operation in the request, while
resource_name
in ad_group_ad_operation
is not necessary since no further
operation is referencing it.
Group same-type operations
When using GoogleAdsService.Mutate
,
it is important to group operations
together according to their resource in the repeated operations array. This
mutate method essentially serves as a way to automatically sequentially call
each individual resource's own mutate method. To do this, it reads in operations
until it finds one for a different type of resources, then batches all the
same-type operations together in one request.
For example, if you have 5 campaign operations, followed by 10 ad group
operations in the repeated operations
field in your Mutate
call, then the
system will perform two total calls in the backend, one to the
CampaignService
for 5 operations, and the next to the AdGroupService
for 10 operations.
However, if you were to group them differently, performance could be a lot
worse. If you only create 2 campaigns and 2 ad groups, but weave them so the
operations are ordered as [campaign, ad group, campaign, ad group], then this
will result in four total calls in the backend. This will result in slower API
performance and in extreme cases can even lead to timeouts.
Retrieve mutable attributes from the response
If you set the response_content_type
of your mutate request to
MUTABLE_RESOURCE
,
the response will contain the values of all mutable fields for every object
created or updated by the request. Use this feature to avoid an additional
search
or searchStream
request after each mutate request.
If you do not set the response_content_type
, then the Google Ads API defaults to
RESOURCE_NAME_ONLY
and the response will only contain the resource name of
each created or updated resource.
Here's an example of retrieving a mutable resource from an API call:
Java
// Constructs a request to add the bid modifier. MutateCampaignBidModifiersRequest request = MutateCampaignBidModifiersRequest.newBuilder() .addOperations(op) .setCustomerId(String.valueOf(customerId)) // Specifies that we want to the request to return the mutated object and not just its // resource name. .setResponseContentType(ResponseContentType.MUTABLE_RESOURCE) .build(); // Sends the operation in a mutate request. try (CampaignBidModifierServiceClient agcServiceClient = googleAdsClient.getLatestVersion().createCampaignBidModifierServiceClient()) { MutateCampaignBidModifiersResponse response = agcServiceClient.mutateCampaignBidModifiers(request); /** * The resource returned in the response can be accessed directly in the results list. Its * fields can be read directly, and it can also be mutated further and used in subsequent * requests, without needing to make additional Get or Search requests. */ CampaignBidModifier mutableResource = response.getResults(0).getCampaignBidModifier(); System.out.printf( "Created campaign bid modifier with resource_name " + "'%s', criterion ID " + "%d, and bid modifier value " + "%s, under the campaign with " + "resource_name '%s'.%n", mutableResource.getResourceName(), mutableResource.getCriterionId(), mutableResource.getBidModifier(), mutableResource.getCampaign()); }
C#
// Construct an operation to create the campaign bid modifier. CampaignBidModifierOperation op = new CampaignBidModifierOperation() { Create = campaignBidModifier }; // Construct a request, and set the ResponseContentType field to // ResponseContentType.MutableResource, so that the response contains // the mutated object and not just its resource name. MutateCampaignBidModifiersRequest request = new MutateCampaignBidModifiersRequest() { CustomerId = customerId.ToString(), ResponseContentType = ResponseContentType.MutableResource, Operations = { op } }; // Send the operation in a mutate request. try { MutateCampaignBidModifiersResponse response = campaignBidModifierService.MutateCampaignBidModifiers(request); Console.WriteLine("Added {0} campaign bid modifiers:", response.Results.Count); // The resource returned in the response can be accessed directly in the // results list. Its fields can be read directly, and it can also be mutated // further and used in subsequent requests, without needing to make // additional Get or Search requests. foreach (MutateCampaignBidModifierResult result in response.Results) { Console.WriteLine($"\tCreated campaign bid modifier with " + $"resource name '{result.ResourceName}', " + $"criterion ID '{result.CampaignBidModifier.CriterionId}', " + $"and bid modifier value {result.CampaignBidModifier.BidModifier}, " + $"under the campaign with resource_name " + $"'{result.CampaignBidModifier.Campaign}'"); } } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; }
PHP
// Issues a mutate request to add the campaign bid modifier. // Here we pass the optional parameter ResponseContentType::MUTABLE_RESOURCE so that the // response contains the mutated object and not just its resource name. $campaignBidModifierServiceClient = $googleAdsClient->getCampaignBidModifierServiceClient(); $response = $campaignBidModifierServiceClient->mutateCampaignBidModifiers( $customerId, [$campaignBidModifierOperation], ['responseContentType' => ResponseContentType::MUTABLE_RESOURCE] ); // The resource returned in the response can be accessed directly in the results list. // Its fields can be read directly, and it can also be mutated further and used in // subsequent requests, without needing to make additional Get or Search requests. /** @var CampaignBidModifier $addedCampaignBidModifier */ $addedCampaignBidModifier = $response->getResults()[0]->getCampaignBidModifier(); printf( "Added campaign bid modifier with resource_name '%s', criterion ID %d, and " . "bid modifier value %f, under the campaign with resource name '%s'.%s", $addedCampaignBidModifier->getResourceName(), $addedCampaignBidModifier->getCriterionId(), $addedCampaignBidModifier->getBidModifier(), $addedCampaignBidModifier->getCampaign(), PHP_EOL );
Python
# Add the campaign bid modifier. Here we pass the optional parameter # response_content_type=MUTABLE_RESOURCE so that the response contains # the mutated object and not just its resource name. request = client.get_type("MutateCampaignBidModifiersRequest") request.customer_id = customer_id request.operations = [campaign_bid_modifier_operation] request.response_content_type = ( client.enums.ResponseContentTypeEnum.MUTABLE_RESOURCE ) campaign_bm_response = campaign_bm_service.mutate_campaign_bid_modifiers( request=request ) # The resource returned in the response can be accessed directly in the # results list. Its fields can be read directly, and it can also be mutated # further and used in subsequent requests, without needing to make # additional Get or Search requests. mutable_resource = campaign_bm_response.results[0].campaign_bid_modifier print( "Created campaign bid modifier with resource_name " f"'{mutable_resource.resource_name}', criterion ID " f"'{mutable_resource.criterion_id}', and bid modifier value " f"'{mutable_resource.bid_modifier}', under the campaign with " f"resource_name '{mutable_resource.campaign}', " )
Ruby
# Add the campaign bid modifier. Here we pass the optional parameter # response_content_type=MUTABLE_RESOURCE so that the response contains # the mutated object and not just its resource name. response = campaign_bid_modifier_service.mutate_campaign_bid_modifiers( customer_id: customer_id, operations: [operation], response_content_type: :MUTABLE_RESOURCE, ) puts "Added #{response.results.size} campaign bid modifiers:" response.results.each do |added_campaign_bid_modifier| # The resource returned in the response can be accessed directly in the # results list. Its fields can be read directly, and it can also be mutated # further and used in subsequent requests, without needing to make # additional Get or Search requests. mutable_resource = added_campaign_bid_modifier.campaign_bid_modifier puts "\tCreated campaign bid modifier with " \ "resource_name '#{mutable_resource.resource_name}', " \ "criterion ID #{mutable_resource.criterion_id}, " \ "bid_modifier #{mutable_resource.bid_modifier}, " \ "under the campaign with resource_name '#{mutable_resource.campaign}'" end
Perl
# Add the campaign bid modifier. Here we pass the optional parameter # responseContentType => MUTABLE_RESOURCE so that the response contains the # mutated object and not just its resource name. my $campaign_bid_modifiers_response = $api_client->CampaignBidModifierService()->mutate({ customerId => $customer_id, operations => [$campaign_bid_modifier_operation], responseContentType => MUTABLE_RESOURCE }); # The resource returned in the response can be accessed directly in the # results list. Its fields can be read directly, and it can also be mutated # further and used in subsequent requests, without needing to make additional # Get or Search requests. my $mutable_resource = $campaign_bid_modifiers_response->{results}[0]{campaignBidModifier}; printf "Created campaign bid modifier with resource name '%s', criterion ID %d, " . "and bid modifier value %s, under the campaign with resource name '%s'.\n", $mutable_resource->{resourceName}, $mutable_resource->{criterionId}, $mutable_resource->{bidModifier}, $mutable_resource->{campaign};