github.com/grpc-ecosystem/grpc-gateway/v2@v2.19.1/internal/descriptor/openapi_configuration.go (about) 1 package descriptor 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 8 "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig" 9 "google.golang.org/protobuf/encoding/protojson" 10 "gopkg.in/yaml.v3" 11 ) 12 13 func loadOpenAPIConfigFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*openapiconfig.OpenAPIConfig, error) { 14 var yamlContents interface{} 15 if err := yaml.Unmarshal(yamlFileContents, &yamlContents); err != nil { 16 return nil, fmt.Errorf("failed to parse gRPC API Configuration from YAML in %q: %w", yamlSourceLogName, err) 17 } 18 19 jsonContents, err := json.Marshal(yamlContents) 20 if err != nil { 21 return nil, err 22 } 23 24 // Reject unknown fields because OpenAPIConfig is only used here 25 unmarshaler := protojson.UnmarshalOptions{ 26 DiscardUnknown: false, 27 } 28 29 openapiConfiguration := openapiconfig.OpenAPIConfig{} 30 if err := unmarshaler.Unmarshal(jsonContents, &openapiConfiguration); err != nil { 31 return nil, fmt.Errorf("failed to parse OpenAPI Configuration from YAML in %q: %w", yamlSourceLogName, err) 32 } 33 34 return &openapiConfiguration, nil 35 } 36 37 func registerOpenAPIOptions(registry *Registry, openAPIConfig *openapiconfig.OpenAPIConfig, yamlSourceLogName string) error { 38 if openAPIConfig.OpenapiOptions == nil { 39 // Nothing to do 40 return nil 41 } 42 43 if err := registry.RegisterOpenAPIOptions(openAPIConfig.OpenapiOptions); err != nil { 44 return fmt.Errorf("failed to register option in %s: %w", yamlSourceLogName, err) 45 } 46 return nil 47 } 48 49 // LoadOpenAPIConfigFromYAML loads an OpenAPI Configuration from the given YAML file 50 // and registers the OpenAPI options the given registry. 51 // This must be done after loading the proto file. 52 func (r *Registry) LoadOpenAPIConfigFromYAML(yamlFile string) error { 53 yamlFileContents, err := os.ReadFile(yamlFile) 54 if err != nil { 55 return fmt.Errorf("failed to read OpenAPI Configuration description from %q: %w", yamlFile, err) 56 } 57 58 config, err := loadOpenAPIConfigFromYAML(yamlFileContents, yamlFile) 59 if err != nil { 60 return err 61 } 62 63 return registerOpenAPIOptions(r, config, yamlFile) 64 }