Skip to content

Commit

Permalink
Support x-databricks-path-style overrides at the operation level (#562)
Browse files Browse the repository at this point in the history
## Changes
In order to support multiple styles of request under a single service,
we introduce support for overriding x-databricks-path-style at the
Operation level. This will allow RPC- and REST-style operations to exist
under a single service. To determine the path style for a method, we
check for a method-level override, falling back to the service-level
setting. If neither is set, the path style is assumed to be "rest".

## Tests
Tested by regenerating the Python SDK using a spec I edited by hand to
include this extension at the operation level. The generated code was as
I expected (using the operation ID to derive name in the Clusters
service, which is normally an RPC style service).

- [ ] `make test` passing
- [ ] `make fmt` applied
- [ ] relevant integration tests applied
  • Loading branch information
mgyucht authored Jul 27, 2023
1 parent cf4ac71 commit da7424a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
6 changes: 5 additions & 1 deletion openapi/code/method.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ type Method struct {
Response *Entity
EmptyResponseName Named

// The style of the request, either "rpc" or "rest". See the documentation on
// Operation for more details.
PathStyle openapi.PathStyle

// For list APIs, the path of fields in the response entity to follow to get
// the resource ID.
IdFieldPath []*Field
Expand Down Expand Up @@ -105,7 +109,7 @@ func (m *Method) allowShortcut() bool {
if m.shortcut {
return true
}
if m.Service.IsRpcStyle {
if m.PathStyle == openapi.PathStyleRpc {
return true
}
return false
Expand Down
2 changes: 1 addition & 1 deletion openapi/code/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func (pkg *Package) Load(spec *openapi.Specification, tag openapi.Tag) error {
svc = &Service{
Package: pkg,
IsAccounts: tag.IsAccounts,
IsRpcStyle: tag.PathStyle == "rpc",
PathStyle: tag.PathStyle,
methods: map[string]*Method{},
Named: Named{
Name: tag.Service,
Expand Down
16 changes: 14 additions & 2 deletions openapi/code/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
// Service represents specific Databricks API
type Service struct {
Named
IsRpcStyle bool
PathStyle openapi.PathStyle
IsAccounts bool
Package *Package
methods map[string]*Method
Expand Down Expand Up @@ -245,6 +245,16 @@ func (svc *Service) paramPath(path string, request *Entity, params []openapi.Par
return
}

func (svc *Service) getPathStyle(op *openapi.Operation) openapi.PathStyle {
if op.PathStyle != "" {
return op.PathStyle
}
if svc.PathStyle != "" {
return svc.PathStyle
}
return openapi.PathStyleRest
}

func (svc *Service) newMethod(verb, path string, params []openapi.Parameter, op *openapi.Operation) *Method {
request := svc.newRequest(params, op)
respSchema := op.SuccessResponseSchema(svc.Package.Components)
Expand All @@ -255,7 +265,8 @@ func (svc *Service) newMethod(verb, path string, params []openapi.Parameter, op
emptyResponse = response.Named
response = nil
}
if svc.IsRpcStyle {
requestStyle := svc.getPathStyle(op)
if requestStyle == openapi.PathStyleRpc {
name = filepath.Base(path)
}
description := op.Description
Expand Down Expand Up @@ -296,6 +307,7 @@ func (svc *Service) newMethod(verb, path string, params []openapi.Parameter, op
PathParts: svc.paramPath(path, request, params),
Response: response,
EmptyResponseName: emptyResponse,
PathStyle: requestStyle,
NameFieldPath: nameFieldPath,
IdFieldPath: idFieldPath,
wait: op.Wait,
Expand Down
48 changes: 43 additions & 5 deletions openapi/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,42 @@ type Specification struct {
Tags []Tag `json:"tags"`
}

type PathStyle string

const (
// PathStyleRpc indicates that the endpoint is an RPC-style endpoint.
// The endpoint path is an action, and the entity to act on is specified
// in the request body.
PathStyleRpc PathStyle = "rpc"

// PathStyleRest indicates that the endpoint is a REST-style endpoint.
// The endpoint path is a resource, and the operation to perform on the
// resource is specified in the HTTP method.
PathStyleRest PathStyle = "rest"
)

func (r *PathStyle) UnmarshalJSON(data []byte) error {
var s string
err := json.Unmarshal(data, &s)
if err != nil {
return fmt.Errorf("cannot unmarshal RequestStyle: %w", err)
}
switch s {
case "rpc", "rest":
*r = PathStyle(s)
default:
return fmt.Errorf("invalid RequestStyle: %s", s)
}
return nil
}

type Tag struct {
Node
Package string `json:"x-databricks-package"`
PathStyle string `json:"x-databricks-path-style"`
Service string `json:"x-databricks-service"`
IsAccounts bool `json:"x-databricks-is-accounts"`
Name string `json:"name"`
Package string `json:"x-databricks-package"`
PathStyle PathStyle `json:"x-databricks-path-style"`
Service string `json:"x-databricks-service"`
IsAccounts bool `json:"x-databricks-is-accounts"`
Name string `json:"name"`
}

type Path struct {
Expand Down Expand Up @@ -100,6 +129,15 @@ type Operation struct {
Crud string `json:"x-databricks-crud,omitempty"`
JsonOnly bool `json:"x-databricks-cli-json-only,omitempty"`

// The x-databricks-path-style field indicates whether the operation has a
// RESTful path style or a RPC style. When specified, this overrides the
// service-level setting. Valid values are "rest" and "rpc". "rest" means
// that the operation has a RESTful path style, i.e. the path represents
// a resource and the HTTP method represents an action on the resource.
// "rpc" means that the operation has a RPC style, i.e. the path represents
// an action and the request body represents the resource.
PathStyle PathStyle `json:"x-databricks-path-style,omitempty"`

// For list APIs, the path to the field in the response entity that contains
// the resource ID.
IdField fieldPath `json:"x-databricks-id,omitempty"`
Expand Down

0 comments on commit da7424a

Please sign in to comment.