diff --git a/google-api-go-generator/gen.go b/google-api-go-generator/gen.go index 5b069cb20da..c30a3608c55 100644 --- a/google-api-go-generator/gen.go +++ b/google-api-go-generator/gen.go @@ -1688,6 +1688,9 @@ func (meth *Method) generateCode() { pn("\n// method id %q:", meth.Id()) retType := responseType(a, meth.m) + if meth.IsRawHTTP() { + retType = "*http.Response" + } retTypeComma := retType if retTypeComma != "" { retTypeComma += ", " @@ -1913,23 +1916,28 @@ func (meth *Method) generateCode() { pn("}") } pn("var body io.Reader = nil") - if ba := args.bodyArg(); ba != nil && httpMethod != "GET" { - if meth.m.ID == "ml.projects.predict" { - // Skip JSONReader for APIs that require clients to pass in JSON already. - pn("body = strings.NewReader(c.%s.HttpBody.Data)", ba.goname) - } else { - style := "WithoutDataWrapper" - if a.needsDataWrapper() { - style = "WithDataWrapper" + if meth.IsRawHTTP() { + pn("body = c.body_") + } else { + if ba := args.bodyArg(); ba != nil && httpMethod != "GET" { + if meth.m.ID == "ml.projects.predict" { + // TODO(cbro): move ML API to rawHTTP (it will be a breaking change) + // Skip JSONReader for APIs that require clients to pass in JSON already. + pn("body = strings.NewReader(c.%s.HttpBody.Data)", ba.goname) + } else { + style := "WithoutDataWrapper" + if a.needsDataWrapper() { + style = "WithDataWrapper" + } + pn("body, err := googleapi.%s.JSONReader(c.%s)", style, ba.goname) + pn("if err != nil { return nil, err }") } - pn("body, err := googleapi.%s.JSONReader(c.%s)", style, ba.goname) - pn("if err != nil { return nil, err }") - } - pn(`reqHeaders.Set("Content-Type", "application/json")`) + pn(`reqHeaders.Set("Content-Type", "application/json")`) + } + pn(`c.urlParams_.Set("alt", alt)`) + pn(`c.urlParams_.Set("prettyPrint", "false")`) } - pn(`c.urlParams_.Set("alt", alt)`) - pn(`c.urlParams_.Set("prettyPrint", "false")`) pn("urls := googleapi.ResolveRelative(c.s.BasePath, %q)", meth.m.Path) if meth.supportsMediaUpload() { @@ -1948,7 +1956,7 @@ func (meth *Method) generateCode() { pn("body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)") pn("defer cleanup()") } - pn("urls += \"?\" + c.urlParams_.Encode()") + pn(`urls += "?" + c.urlParams_.Encode()`) pn("req, err := http.NewRequest(%q, urls, body)", httpMethod) pn("if err != nil { return nil, err }") pn("req.Header = reqHeaders") @@ -1988,7 +1996,7 @@ func (meth *Method) generateCode() { mapRetType := strings.HasPrefix(retTypeComma, "map[") pn("\n// Do executes the %q call.", meth.m.ID) - if retTypeComma != "" && !mapRetType { + if retTypeComma != "" && !mapRetType && !meth.IsRawHTTP() { commentFmtStr := "Exactly one of %v or error will be non-nil. " + "Any non-2xx status code is an error. " + "Response headers are in either %v.ServerResponse.Header " + @@ -2004,67 +2012,71 @@ func (meth *Method) generateCode() { nilRet = "nil, " } pn(`gensupport.SetOptions(c.urlParams_, opts...)`) - pn(`res, err := c.doRequest("json")`) - - if retTypeComma != "" && !mapRetType { - pn("if res != nil && res.StatusCode == http.StatusNotModified {") - pn(" if res.Body != nil { res.Body.Close() }") - pn(" return nil, &googleapi.Error{") - pn(" Code: res.StatusCode,") - pn(" Header: res.Header,") - pn(" }") - pn("}") - } - pn("if err != nil { return %serr }", nilRet) - pn("defer googleapi.CloseBody(res)") - pn("if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet) - if meth.supportsMediaUpload() { - pn(`rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))`) - pn("if rx != nil {") - pn(" rx.Client = c.s.client") - pn(" rx.UserAgent = c.s.userAgent()") - pn(" ctx := c.ctx_") - pn(" if ctx == nil {") - // TODO(mcgreevy): Require context when calling Media, or Do. - pn(" ctx = context.TODO()") - pn(" }") - pn(" res, err = rx.Upload(ctx)") - pn(" if err != nil { return %serr }", nilRet) - pn(" defer res.Body.Close()") - pn(" if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet) - pn("}") - } - if retTypeComma == "" { - pn("return nil") + if meth.IsRawHTTP() { + pn(`return c.doRequest("")`) } else { - if mapRetType { - pn("var ret %s", responseType(a, meth.m)) - } else { - pn("ret := &%s{", responseTypeLiteral(a, meth.m)) - pn(" ServerResponse: googleapi.ServerResponse{") + pn(`res, err := c.doRequest("json")`) + + if retTypeComma != "" && !mapRetType { + pn("if res != nil && res.StatusCode == http.StatusNotModified {") + pn(" if res.Body != nil { res.Body.Close() }") + pn(" return nil, &googleapi.Error{") + pn(" Code: res.StatusCode,") pn(" Header: res.Header,") - pn(" HTTPStatusCode: res.StatusCode,") - pn(" },") + pn(" }") pn("}") } - if a.needsDataWrapper() { - pn("target := &struct {") - pn(" Data %s `json:\"data\"`", responseType(a, meth.m)) - pn("}{ret}") - } else { - pn("target := &ret") + pn("if err != nil { return %serr }", nilRet) + pn("defer googleapi.CloseBody(res)") + pn("if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet) + if meth.supportsMediaUpload() { + pn(`rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))`) + pn("if rx != nil {") + pn(" rx.Client = c.s.client") + pn(" rx.UserAgent = c.s.userAgent()") + pn(" ctx := c.ctx_") + pn(" if ctx == nil {") + // TODO(mcgreevy): Require context when calling Media, or Do. + pn(" ctx = context.TODO()") + pn(" }") + pn(" res, err = rx.Upload(ctx)") + pn(" if err != nil { return %serr }", nilRet) + pn(" defer res.Body.Close()") + pn(" if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet) + pn("}") } - - if meth.m.ID == "ml.projects.predict" { - pn("var b bytes.Buffer") - pn("if _, err := io.Copy(&b, res.Body); err != nil { return nil, err }") - pn("if err := res.Body.Close(); err != nil { return nil, err }") - pn("if err := json.NewDecoder(bytes.NewReader(b.Bytes())).Decode(target); err != nil { return nil, err }") - pn("ret.Data = b.String()") + if retTypeComma == "" { + pn("return nil") } else { - pn("if err := gensupport.DecodeResponse(target, res); err != nil { return nil, err }") + if mapRetType { + pn("var ret %s", responseType(a, meth.m)) + } else { + pn("ret := &%s{", responseTypeLiteral(a, meth.m)) + pn(" ServerResponse: googleapi.ServerResponse{") + pn(" Header: res.Header,") + pn(" HTTPStatusCode: res.StatusCode,") + pn(" },") + pn("}") + } + if a.needsDataWrapper() { + pn("target := &struct {") + pn(" Data %s `json:\"data\"`", responseType(a, meth.m)) + pn("}{ret}") + } else { + pn("target := &ret") + } + + if meth.m.ID == "ml.projects.predict" { + pn("var b bytes.Buffer") + pn("if _, err := io.Copy(&b, res.Body); err != nil { return nil, err }") + pn("if err := res.Body.Close(); err != nil { return nil, err }") + pn("if err := json.NewDecoder(bytes.NewReader(b.Bytes())).Decode(target); err != nil { return nil, err }") + pn("ret.Data = b.String()") + } else { + pn("if err := gensupport.DecodeResponse(target, res); err != nil { return nil, err }") + } + pn("return ret, nil") } - pn("return ret, nil") } bs, err := json.MarshalIndent(meth.m.JSONMap, "\t// ", " ") @@ -2175,6 +2187,14 @@ func resolveRelative(basestr, relstr string) string { return u.String() } +func (meth *Method) IsRawHTTP() bool { + if meth.m.Request == nil { + return false + } + // TODO(cbro): enable across other APIs. + return meth.api.Name == "healthcare" && meth.m.Request.Ref == "HttpBody" +} + func (meth *Method) NewArguments() *arguments { args := &arguments{ method: meth, @@ -2193,7 +2213,14 @@ func (meth *Method) NewArguments() *arguments { args.AddArg(arg) } if rs := meth.m.Request; rs != nil { - args.AddArg(meth.NewBodyArg(rs)) + if meth.IsRawHTTP() { + args.AddArg(&argument{ + goname: "body_", + gotype: "io.Reader", + }) + } else { + args.AddArg(meth.NewBodyArg(rs)) + } } return args } diff --git a/google-api-go-generator/gen_test.go b/google-api-go-generator/gen_test.go index 0f353bafaba..c01338e9ecd 100644 --- a/google-api-go-generator/gen_test.go +++ b/google-api-go-generator/gen_test.go @@ -37,6 +37,7 @@ func TestAPIs(t *testing.T) { "blogger-3", "floats", "getwithoutbody", + "http-body", "json-body", "mapofany", "mapofarrayofobjects", diff --git a/google-api-go-generator/testdata/http-body.json b/google-api-go-generator/testdata/http-body.json new file mode 100644 index 00000000000..f016732a473 --- /dev/null +++ b/google-api-go-generator/testdata/http-body.json @@ -0,0 +1,199 @@ +{ + "fullyEncodeReservedExpansion": true, + "title": "Cloud Healthcare API", + "ownerName": "Google", + "resources": { + "projects": { + "resources": { + "locations": { + "resources": { + "datasets": { + "resources": { + "fhirStores": { + "resources": { + "fhir": { + "methods": { + "createResource": { + "description": "Creates a FHIR resource.\n", + "request": { + "$ref": "HttpBody" + }, + "response": { + "$ref": "HttpBody" + }, + "parameterOrder": [ + "parent", + "type" + ], + "httpMethod": "POST", + "parameters": { + "type": { + "pattern": "^[^/]+$", + "location": "path", + "description": "The type of the resource to create.", + "required": true, + "type": "string" + }, + "parent": { + "description": "The name of the FHIR store this resource belongs to.", + "required": true, + "type": "string", + "pattern": "^projects/[^/]+/locations/[^/]+/datasets/[^/]+/fhirStores/[^/]+$", + "location": "path" + } + }, + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform" + ], + "flatPath": "v1beta1/projects/{projectsId}/locations/{locationsId}/datasets/{datasetsId}/fhirStores/{fhirStoresId}/fhir/{fhirId}", + "path": "v1beta1/{+parent}/fhir/{+type}", + "id": "healthcare.projects.locations.datasets.fhirStores.fhir.createResource" + } + } + } + } + } + } + } + } + } + } + } + }, + "parameters": { + "callback": { + "description": "JSONP", + "type": "string", + "location": "query" + }, + "oauth_token": { + "location": "query", + "description": "OAuth 2.0 token for the current user.", + "type": "string" + }, + "$.xgafv": { + "enumDescriptions": [ + "v1 error format", + "v2 error format" + ], + "location": "query", + "enum": [ + "1", + "2" + ], + "description": "V1 error format.", + "type": "string" + }, + "alt": { + "enum": [ + "json", + "media", + "proto" + ], + "type": "string", + "enumDescriptions": [ + "Responses with Content-Type of application/json", + "Media download with context-dependent Content-Type", + "Responses with Content-Type of application/x-protobuf" + ], + "location": "query", + "description": "Data format for response.", + "default": "json" + }, + "access_token": { + "description": "OAuth access token.", + "type": "string", + "location": "query" + }, + "key": { + "location": "query", + "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", + "type": "string" + }, + "upload_protocol": { + "location": "query", + "description": "Upload protocol for media (e.g. \"raw\", \"multipart\").", + "type": "string" + }, + "quotaUser": { + "location": "query", + "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.", + "type": "string" + }, + "prettyPrint": { + "description": "Returns response with indentations and line breaks.", + "type": "boolean", + "default": "true", + "location": "query" + }, + "fields": { + "description": "Selector specifying which fields to include in a partial response.", + "type": "string", + "location": "query" + }, + "uploadType": { + "description": "Legacy upload protocol for media (e.g. \"media\", \"multipart\").", + "type": "string", + "location": "query" + } + }, + "version": "v1beta1", + "baseUrl": "https://healthcare.googleapis.com/", + "kind": "discovery#restDescription", + "description": "Manage, store, and access healthcare data in Google Cloud Platform.", + "servicePath": "", + "basePath": "", + "revision": "20190321", + "documentationLink": "https://cloud.google.com/healthcare", + "id": "healthcare:v1beta1", + "discoveryVersion": "v1", + "version_module": true, + "schemas": { + "HttpBody": { + "description": "Message that represents an arbitrary HTTP body. It should only be used for\npayload formats that can't be represented as JSON, such as raw binary or\nan HTML page.\n\n\nThis message can be used both in streaming and non-streaming API methods in\nthe request as well as the response.\n\nIt can be used as a top-level request field, which is convenient if one\nwants to extract parameters from either the URL or HTTP template into the\nrequest fields and also want access to the raw HTTP body.\n\nExample:\n\n message GetResourceRequest {\n // A unique request id.\n string request_id = 1;\n\n // The raw HTTP body is bound to this field.\n google.api.HttpBody http_body = 2;\n }\n\n service ResourceService {\n rpc GetResource(GetResourceRequest) returns (google.api.HttpBody);\n rpc UpdateResource(google.api.HttpBody) returns (google.protobuf.Empty);\n }\n\nExample with streaming methods:\n\n service CaldavService {\n rpc GetCalendar(stream google.api.HttpBody)\n returns (stream google.api.HttpBody);\n rpc UpdateCalendar(stream google.api.HttpBody)\n returns (stream google.api.HttpBody);\n }\n\nUse of this type only changes how the request and response bodies are\nhandled, all other features will continue to work unchanged.", + "type": "object", + "properties": { + "data": { + "description": "The HTTP request/response body as raw binary.", + "format": "byte", + "type": "string" + }, + "contentType": { + "description": "The HTTP Content-Type header value specifying the content type of the body.", + "type": "string" + }, + "extensions": { + "description": "Application specific response metadata. Must be set in the first response\nfor streaming APIs.", + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "description": "Properties of the object. Contains field @type with type URL.", + "type": "any" + } + } + } + }, + "id": "HttpBody" + } + }, + "protocol": "rest", + "icons": { + "x32": "http://www.google.com/images/icons/product/search-32.gif", + "x16": "http://www.google.com/images/icons/product/search-16.gif" + }, + "canonicalName": "Cloud Healthcare", + "auth": { + "oauth2": { + "scopes": { + "https://www.googleapis.com/auth/cloud-platform": { + "description": "View and manage your data across Google Cloud Platform services" + } + } + } + }, + "rootUrl": "https://healthcare.googleapis.com/", + "ownerDomain": "google.com", + "name": "healthcare", + "batchPath": "batch" +} \ No newline at end of file diff --git a/google-api-go-generator/testdata/http-body.want b/google-api-go-generator/testdata/http-body.want new file mode 100644 index 00000000000..7c88f6ae377 --- /dev/null +++ b/google-api-go-generator/testdata/http-body.want @@ -0,0 +1,386 @@ +// Copyright YEAR Google LLC. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated file. DO NOT EDIT. + +// Package healthcare provides access to the Cloud Healthcare API. +// +// For product documentation, see: https://cloud.google.com/healthcare +// +// Creating a client +// +// Usage example: +// +// import "google.golang.org/api/healthcare/v1beta1" +// ... +// ctx := context.Background() +// healthcareService, err := healthcare.NewService(ctx) +// +// In this example, Google Application Default Credentials are used for authentication. +// +// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials. +// +// Other authentication options +// +// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey: +// +// healthcareService, err := healthcare.NewService(ctx, option.WithAPIKey("AIza...")) +// +// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource: +// +// config := &oauth2.Config{...} +// // ... +// token, err := config.Exchange(ctx, ...) +// healthcareService, err := healthcare.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token))) +// +// See https://godoc.org/google.golang.org/api/option/ for details on options. +package healthcare // import "google.golang.org/api/healthcare/v1beta1" + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + + gensupport "google.golang.org/api/gensupport" + googleapi "google.golang.org/api/googleapi" + option "google.golang.org/api/option" + htransport "google.golang.org/api/transport/http" +) + +// Always reference these packages, just in case the auto-generated code +// below doesn't. +var _ = bytes.NewBuffer +var _ = strconv.Itoa +var _ = fmt.Sprintf +var _ = json.NewDecoder +var _ = io.Copy +var _ = url.Parse +var _ = gensupport.MarshalJSON +var _ = googleapi.Version +var _ = errors.New +var _ = strings.Replace +var _ = context.Canceled + +const apiId = "healthcare:v1beta1" +const apiName = "healthcare" +const apiVersion = "v1beta1" +const basePath = "https://healthcare.googleapis.com/" + +// OAuth2 scopes used by this API. +const ( + // View and manage your data across Google Cloud Platform services + CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform" +) + +// NewService creates a new Service. +func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) { + scopesOption := option.WithScopes( + "https://www.googleapis.com/auth/cloud-platform", + ) + // NOTE: prepend, so we don't override user-specified scopes. + opts = append([]option.ClientOption{scopesOption}, opts...) + client, endpoint, err := htransport.NewClient(ctx, opts...) + if err != nil { + return nil, err + } + s, err := New(client) + if err != nil { + return nil, err + } + if endpoint != "" { + s.BasePath = endpoint + } + return s, nil +} + +// New creates a new Service. It uses the provided http.Client for requests. +// +// Deprecated: please use NewService instead. +// To provide a custom HTTP client, use option.WithHTTPClient. +// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead. +func New(client *http.Client) (*Service, error) { + if client == nil { + return nil, errors.New("client is nil") + } + s := &Service{client: client, BasePath: basePath} + s.Projects = NewProjectsService(s) + return s, nil +} + +type Service struct { + client *http.Client + BasePath string // API endpoint base URL + UserAgent string // optional additional User-Agent fragment + + Projects *ProjectsService +} + +func (s *Service) userAgent() string { + if s.UserAgent == "" { + return googleapi.UserAgent + } + return googleapi.UserAgent + " " + s.UserAgent +} + +func NewProjectsService(s *Service) *ProjectsService { + rs := &ProjectsService{s: s} + rs.Locations = NewProjectsLocationsService(s) + return rs +} + +type ProjectsService struct { + s *Service + + Locations *ProjectsLocationsService +} + +func NewProjectsLocationsService(s *Service) *ProjectsLocationsService { + rs := &ProjectsLocationsService{s: s} + rs.Datasets = NewProjectsLocationsDatasetsService(s) + return rs +} + +type ProjectsLocationsService struct { + s *Service + + Datasets *ProjectsLocationsDatasetsService +} + +func NewProjectsLocationsDatasetsService(s *Service) *ProjectsLocationsDatasetsService { + rs := &ProjectsLocationsDatasetsService{s: s} + rs.FhirStores = NewProjectsLocationsDatasetsFhirStoresService(s) + return rs +} + +type ProjectsLocationsDatasetsService struct { + s *Service + + FhirStores *ProjectsLocationsDatasetsFhirStoresService +} + +func NewProjectsLocationsDatasetsFhirStoresService(s *Service) *ProjectsLocationsDatasetsFhirStoresService { + rs := &ProjectsLocationsDatasetsFhirStoresService{s: s} + rs.Fhir = NewProjectsLocationsDatasetsFhirStoresFhirService(s) + return rs +} + +type ProjectsLocationsDatasetsFhirStoresService struct { + s *Service + + Fhir *ProjectsLocationsDatasetsFhirStoresFhirService +} + +func NewProjectsLocationsDatasetsFhirStoresFhirService(s *Service) *ProjectsLocationsDatasetsFhirStoresFhirService { + rs := &ProjectsLocationsDatasetsFhirStoresFhirService{s: s} + return rs +} + +type ProjectsLocationsDatasetsFhirStoresFhirService struct { + s *Service +} + +// HttpBody: Message that represents an arbitrary HTTP body. It should +// only be used for +// payload formats that can't be represented as JSON, such as raw binary +// or +// an HTML page. +// +// +// This message can be used both in streaming and non-streaming API +// methods in +// the request as well as the response. +// +// It can be used as a top-level request field, which is convenient if +// one +// wants to extract parameters from either the URL or HTTP template into +// the +// request fields and also want access to the raw HTTP body. +// +// Example: +// +// message GetResourceRequest { +// // A unique request id. +// string request_id = 1; +// +// // The raw HTTP body is bound to this field. +// google.api.HttpBody http_body = 2; +// } +// +// service ResourceService { +// rpc GetResource(GetResourceRequest) returns +// (google.api.HttpBody); +// rpc UpdateResource(google.api.HttpBody) returns +// (google.protobuf.Empty); +// } +// +// Example with streaming methods: +// +// service CaldavService { +// rpc GetCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// rpc UpdateCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// } +// +// Use of this type only changes how the request and response bodies +// are +// handled, all other features will continue to work unchanged. +type HttpBody struct { + // ContentType: The HTTP Content-Type header value specifying the + // content type of the body. + ContentType string `json:"contentType,omitempty"` + + // Data: The HTTP request/response body as raw binary. + Data string `json:"data,omitempty"` + + // Extensions: Application specific response metadata. Must be set in + // the first response + // for streaming APIs. + Extensions []googleapi.RawMessage `json:"extensions,omitempty"` + + // ServerResponse contains the HTTP response code and headers from the + // server. + googleapi.ServerResponse `json:"-"` + + // ForceSendFields is a list of field names (e.g. "ContentType") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "ContentType") to include + // in API requests with the JSON null value. By default, fields with + // empty values are omitted from API requests. However, any field with + // an empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *HttpBody) MarshalJSON() ([]byte, error) { + type NoMethod HttpBody + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + +// method id "healthcare.projects.locations.datasets.fhirStores.fhir.createResource": + +type ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall struct { + s *Service + parent string + type_ string + body_ io.Reader + urlParams_ gensupport.URLParams + ctx_ context.Context + header_ http.Header +} + +// CreateResource: Creates a FHIR resource. +// +func (r *ProjectsLocationsDatasetsFhirStoresFhirService) CreateResource(parent string, type_ string, body_ io.Reader) *ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall { + c := &ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall{s: r.s, urlParams_: make(gensupport.URLParams)} + c.parent = parent + c.type_ = type_ + c.body_ = body_ + return c +} + +// Fields allows partial responses to be retrieved. See +// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse +// for more information. +func (c *ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall) Fields(s ...googleapi.Field) *ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall { + c.urlParams_.Set("fields", googleapi.CombineFields(s)) + return c +} + +// Context sets the context to be used in this call's Do method. Any +// pending HTTP request will be aborted if the provided context is +// canceled. +func (c *ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall) Context(ctx context.Context) *ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall { + c.ctx_ = ctx + return c +} + +// Header returns an http.Header that can be modified by the caller to +// add HTTP headers to the request. +func (c *ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall) Header() http.Header { + if c.header_ == nil { + c.header_ = make(http.Header) + } + return c.header_ +} + +func (c *ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall) doRequest(alt string) (*http.Response, error) { + reqHeaders := make(http.Header) + for k, v := range c.header_ { + reqHeaders[k] = v + } + reqHeaders.Set("User-Agent", c.s.userAgent()) + var body io.Reader = nil + body = c.body_ + urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+parent}/fhir/{+type}") + urls += "?" + c.urlParams_.Encode() + req, err := http.NewRequest("POST", urls, body) + if err != nil { + return nil, err + } + req.Header = reqHeaders + googleapi.Expand(req.URL, map[string]string{ + "parent": c.parent, + "type": c.type_, + }) + return gensupport.SendRequest(c.ctx_, c.s.client, req) +} + +// Do executes the "healthcare.projects.locations.datasets.fhirStores.fhir.createResource" call. +func (c *ProjectsLocationsDatasetsFhirStoresFhirCreateResourceCall) Do(opts ...googleapi.CallOption) (*http.Response, error) { + gensupport.SetOptions(c.urlParams_, opts...) + return c.doRequest("") + // { + // "description": "Creates a FHIR resource.\n", + // "flatPath": "v1beta1/projects/{projectsId}/locations/{locationsId}/datasets/{datasetsId}/fhirStores/{fhirStoresId}/fhir/{fhirId}", + // "httpMethod": "POST", + // "id": "healthcare.projects.locations.datasets.fhirStores.fhir.createResource", + // "parameterOrder": [ + // "parent", + // "type" + // ], + // "parameters": { + // "parent": { + // "description": "The name of the FHIR store this resource belongs to.", + // "location": "path", + // "pattern": "^projects/[^/]+/locations/[^/]+/datasets/[^/]+/fhirStores/[^/]+$", + // "required": true, + // "type": "string" + // }, + // "type": { + // "description": "The type of the resource to create.", + // "location": "path", + // "pattern": "^[^/]+$", + // "required": true, + // "type": "string" + // } + // }, + // "path": "v1beta1/{+parent}/fhir/{+type}", + // "request": { + // "$ref": "HttpBody" + // }, + // "response": { + // "$ref": "HttpBody" + // }, + // "scopes": [ + // "https://www.googleapis.com/auth/cloud-platform" + // ] + // } + +}