Repository: getkin/kin-openapi
Pull request #179 (2020-02-20 08:16:25)

link to github.com/dunglas/vulcain in readme is broken
nothing to say but fixed it :)


Patch:
diff --git a/README.md b/README.md
index cc528e6..fd3db0f 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ Here's some projects that depend on _kin-openapi_:
   * [github.com/getkin/kin](https://github.com/getkin/kin) - "A configurable backend"
   * [github.com/danielgtaylor/apisprout](https://github.com/danielgtaylor/apisprout) - "Lightweight, blazing fast, cross-platform OpenAPI 3 mock server with validation"
   * [github.com/deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) - Generate Go server boilerplate from an OpenAPI 3 spec
-  * [github.com/dunglas/vulcain](https//github.com/dunglas/vulcain) - "Use HTTP/2 Server Push to create fast and idiomatic client-driven REST APIs"
+  * [github.com/dunglas/vulcain](https://github.com/dunglas/vulcain) - "Use HTTP/2 Server Push to create fast and idiomatic client-driven REST APIs"
   * (Feel free to add your project by [creating an issue](https://github.com/getkin/kin-openapi/issues/new) or a pull request)
 
 ## Alternative projects
@@ -193,4 +193,4 @@ func main() {
 func arrayUniqueItemsChecker(items []interface{}) bool {
 	// Check the uniqueness of the input slice(array in JSON)
 }
-```
\ No newline at end of file
+```
diff --git a/openapi3/swagger_loader.go b/openapi3/swagger_loader.go
index 1a5fda1..84521d4 100644
--- a/openapi3/swagger_loader.go
+++ b/openapi3/swagger_loader.go
@@ -535,6 +535,11 @@ func (swaggerLoader *SwaggerLoader) resolveResponseRef(swagger *Swagger, compone
 			contentType.Schema = schema
 		}
 	}
+	for _, link := range value.Links {
+		if err := swaggerLoader.resolveLinkRef(swagger, link, refDocumentPath); err != nil {
+			return err
+		}
+	}
 	return nil
 }
 
@@ -705,6 +710,45 @@ func (swaggerLoader *SwaggerLoader) resolveExampleRef(swagger *Swagger, componen
 	return nil
 }
 
+func (swaggerLoader *SwaggerLoader) resolveLinkRef(swagger *Swagger, component *LinkRef, path *url.URL) error {
+	// Prevent infinite recursion
+	visited := swaggerLoader.visited
+	if _, isVisited := visited[component]; isVisited {
+		return nil
+	}
+	visited[component] = struct{}{}
+
+	const prefix = "#/components/links/"
+	if ref := component.Ref; len(ref) > 0 {
+		if isSingleRefElement(ref) {
+			var link Link
+			if err := swaggerLoader.loadSingleElementFromURI(ref, path, &link); err != nil {
+				return err
+			}
+
+			component.Value = &link
+		} else {
+			components, id, componentPath, err := swaggerLoader.resolveComponent(swagger, ref, prefix, path)
+			if err != nil {
+				return err
+			}
+			definitions := components.Links
+			if definitions == nil {
+				return failedToResolveRefFragmentPart(ref, "links")
+			}
+			resolved := definitions[id]
+			if resolved == nil {
+				return failedToResolveRefFragmentPart(ref, id)
+			}
+			if err := swaggerLoader.resolveLinkRef(swagger, resolved, componentPath); err != nil {
+				return err
+			}
+			component.Value = resolved.Value
+		}
+	}
+	return nil
+}
+
 func (swaggerLoader *SwaggerLoader) resolvePathItemRef(swagger *Swagger, entrypoint string, pathItem *PathItem, documentPath *url.URL) (err error) {
 	// Prevent infinite recursion
 	visited := swaggerLoader.visitedFiles


Test patch:
diff --git a/openapi3/swagger_loader_test.go b/openapi3/swagger_loader_test.go
index b5d1194..62b0c48 100644
--- a/openapi3/swagger_loader_test.go
+++ b/openapi3/swagger_loader_test.go
@@ -443,3 +443,48 @@ func TestLoadYamlFileWithExternalPathRef(t *testing.T) {
 	require.NotNil(t, swagger.Paths["/test"].Get.Responses["200"].Value.Content["application/json"].Schema.Value.Type)
 	require.Equal(t, "string", swagger.Paths["/test"].Get.Responses["200"].Value.Content["application/json"].Schema.Value.Type)
 }
+
+func TestResolveResponseLinkRef(t *testing.T) {
+	source := []byte(`
+openapi: 3.0.1
+info:
+  title: My API
+  version: 1.0.0
+components:
+  links:
+    Father:
+        description: link to to the father
+        operationId: getUserById
+        parameters:
+          "id": "$response.body#/fatherId"
+paths:
+  /users/{id}:
+    get:
+      operationId: getUserById,
+      parameters:
+        - name: id,
+          in: path
+          schema:
+            type: string
+      responses:
+        200:
+          description: A test response
+          content:
+            application/json:
+          links:
+            father:
+              $ref: '#/components/links/Father'
+`)
+	loader := openapi3.NewSwaggerLoader()
+	doc, err := loader.LoadSwaggerFromData(source)
+	require.NoError(t, err)
+
+	err = doc.Validate(loader.Context)
+	require.NoError(t, err)
+
+	response := doc.Paths[`/users/{id}`].Get.Responses.Get(200).Value
+	link := response.Links[`father`].Value
+	require.NotNil(t, link)
+	require.Equal(t, "getUserById", link.OperationID)
+	require.Equal(t, "link to to the father", link.Description)
+}