AIP-153
Import and export
Many users want to be able to load data into an API, or get their existing data out of an API. This is particularly important for enterprise users, who are often concerned about vendor lock-in.
Guidance
APIs may support import and export operations, which may create multiple new resources, or they may populate data into a single resource.
Multiple resources
Services may support importing and exporting multiple resources into or out of an API, and should implement a common pattern to do so:
rpc ImportBooks(ImportBooksRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{parent=publishers/*}/books:import"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "ImportBooksResponse"
metadata_type: "ImportBooksMetadata"
};
}
rpc ExportBooks(ExportBooksRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{parent=publishers/*}/books:export"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "ExportBooksResponse"
metadata_type: "ExportBooksMetadata"
};
}
- The method must return a long-running operation (see AIP-151) unless the service can guarantee that it will never need more than a few seconds to complete.
- The HTTP verb must be
POST
, and thebody
must be"*"
. - A
parent
field should be included as part of the URI.- If importing into or exporting from multiple resources is required, the API
should keep the
parent
field and allow the user to use the-
character to indicate multiple parents (see AIP-159). - On import, if the user provides a specific parent, the API must reject any imported resources that would be added to a different parent.
- If importing into or exporting from multiple resources is required, the API
should keep the
- The URI suffix should be
:import
or:export
.
Data for a single resource
Services may support importing and exporting data into or out of a single resource, and should implement a common pattern to do so:
rpc ImportPages(ImportPagesRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{book=publishers/*/books/*}:importPages"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "ImportPagesResponse"
metadata_type: "ImportPagesMetadata"
};
}
rpc ExportPages(ExportPagesRequest) returns (google.longrunning.Operation) {
option (google.api.http) = {
post: "/v1/{book=publishers/*/books/*}:exportPages"
body: "*"
};
option (google.longrunning.operation_info) = {
response_type: "ExportPagesResponse"
metadata_type: "ExportPagesMetadata"
};
}
- The method must return a long-running operation (see AIP-151) unless the service can guarantee that it will never need more than a few seconds to complete.
- The HTTP verb must be
POST
, and thebody
must be"*"
. - A field representing the resource that data is being imported into should
be included as part of the URI. The field should be named after the
resource (and should not be called
name
). - The URI suffix should include both the verb and a noun for the data itself,
such as
:importPages
or:exportPages
.
Request object
Imports and exports often require two fundamentally different types of configuration:
- Configuration specific to the source or destination.
- Configuration regarding the imported or exported data itself.
Source or destination configuration should be grouped into a single message and placed inside a oneof:
message ImportBooksRequest {
string parent = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
child_type: "library.googleapis.com/Book"
}];
oneof source {
AuthorSource author_source = 2;
TranslatorSource translator_source = 3;
}
string isbn_prefix = 4;
}
message ExportBooksRequest {
string parent = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {
child_type: "library.googleapis.com/Book"
}];
oneof destination {
PrinterDestination printer_destination = 2;
TranslatorDestination translator_destination = 3;
}
string filter = 4;
}
- The source configuration messages must be placed within a
oneof source
(for import) oroneof destination
(for export), even if there is only one. (This maintains flexibility to add more later.) - Configuration related to the data itself (and therefore common across all sources) must be placed at the top-level of the request message.
Note: The configuration for import and export may be different from one another. (For example, it would be sensible to import from a file but export to a directory.)
Inline sources
APIs may also permit import and export "inline", where the contents to be imported or exported are provided in the request or response.
message InlineSource {
repeated Book books = 1;
}
- The source or destination should be named
InlineSource
orInlineDestination
. - The message should include a repeated field representing the resource. However, if the resource structure is complex, the API may use a separate inline representation. In this situation, the same format must be used for both import and export.
Partial failures
While partial failures are normally discouraged, import and export RPCs
should include partial failure information in the metadata object. Each
individual error should be a google.rpc.Status
object describing the
error. For more on errors, see AIP-193.