Swiftpack.co - Package - mattpolzin/JSONAPI-OpenAPI

JSONAPI+OpenAPI

MIT license Swift 5.1 Build Status

See parent project: https://github.com/mattpolzin/JSONAPI

The JSONAPIOpenAPI framework adds the ability to generate OpenAPI compliant JSON Schema documentation of a JSONAPI Document.

There is experimental support for generating JSONAPI Swift code from OpenAPI documentation on the feature/gen-swift branch. There is no formal documentation for this functionality, but it is an area of interest of mine. Reach out to me directly if you would like to know more.

See the Open API Spec here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md

This library is in its infancy. The documentation will grow as the framework becomes more complete.

Simple Example

You can try this out in the included Playground.

import Foundation
import JSONAPI
import OpenAPIKit
import JSONAPIOpenAPI
import Sampleable

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted

//
// First describe the resource object
//
struct WidgetDescription: JSONAPI.ResourceObjectDescription {
    static var jsonType: String { return "widgets" }

    struct Attributes: JSONAPI.Attributes {
        let productName: Attribute<String>
    }

    struct Relationships: JSONAPI.Relationships {
        let subcomponents: ToManyRelationship<Widget, NoMetadata, NoLinks>
    }
}

typealias Widget = JSONAPI.ResourceObject<WidgetDescription, NoMetadata, NoLinks, String>

//
// Then make things sampleable
// This is needed because the only way to use reflection on
// your attributes and relationships structs is to create
// instances of them.
//
extension WidgetDescription.Attributes: Sampleable {
    static var sample: WidgetDescription.Attributes {
        return .init(productName: .init(value: "Fillihizzer Nob Hub"))
    }
}

extension WidgetDescription.Relationships: Sampleable {
    static var sample: WidgetDescription.Relationships {
        return .init(subcomponents: .init(ids: [.init(rawValue: "1")]))
    }
}

//
// We can create a JSON Schema for the Widget at this point
//
let widgetJSONSchema = Widget.openAPISchema(using: encoder)

//
// Describe a JSON:API response body with 1 widget and
// any number of related widgets included.
//
typealias SingleWidgetDocumentWithIncludes = Document<SingleResourceBody<Widget>, NoMetadata, NoLinks, Include1<Widget>, NoAPIDescription, BasicJSONAPIError<String>>

//
// Finally we can create a JSON Schema for the response body of a successful request
//
let jsonAPIResponseSchema = SingleWidgetDocumentWithIncludes.SuccessDocument.openAPISchema(using: encoder)

print(String(data: try! encoder.encode(jsonAPIResponseSchema), encoding: .utf8)!)

//
// Or a failed request
//
let jsonAPIResponseErrorSchema = SingleWidgetDocumentWithIncludes.ErrorDocument.openAPISchema(using: encoder)

//
// Or a schema describing the response as `oneOf` the success or error respones
//
let jsonAPIResponseFullSchema = SingleWidgetDocumentWithIncludes.openAPISchema(using: encoder)

The above code produces:

{
  "type" : "object",
  "properties" : {
    "data" : {
      "type" : "object",
      "properties" : {
        "relationships" : {
          "type" : "object",
          "properties" : {
            "subcomponents" : {
              "type" : "object",
              "properties" : {
                "data" : {
                  "type" : "array",
                  "items" : {
                    "type" : "object",
                    "properties" : {
                      "type" : {
                        "type" : "string",
                        "enum" : [
                          "widgets"
                        ]
                      },
                      "id" : {
                        "type" : "string"
                      }
                    },
                    "required" : [
                      "id",
                      "type"
                    ]
                  }
                }
              },
              "required" : [
                "data"
              ]
            }
          },
          "required" : [
            "subcomponents"
          ]
        },
        "id" : {
          "type" : "string"
        },
        "type" : {
          "type" : "string",
          "enum" : [
            "widgets"
          ]
        },
        "attributes" : {
          "type" : "object",
          "properties" : {
            "productName" : {
              "type" : "string"
            }
          },
          "required" : [
            "productName"
          ]
        }
      },
      "required" : [
        "attributes",
        "id",
        "relationships",
        "type"
      ]
    },
    "included" : {
      "type" : "array",
      "items" : {
        "type" : "object",
        "properties" : {
          "relationships" : {
            "type" : "object",
            "properties" : {
              "subcomponents" : {
                "type" : "object",
                "properties" : {
                  "data" : {
                    "type" : "array",
                    "items" : {
                      "type" : "object",
                      "properties" : {
                        "type" : {
                          "type" : "string",
                          "enum" : [
                            "widgets"
                          ]
                        },
                        "id" : {
                          "type" : "string"
                        }
                      },
                      "required" : [
                        "type",
                        "id"
                      ]
                    }
                  }
                },
                "required" : [
                  "data"
                ]
              }
            },
            "required" : [
              "subcomponents"
            ]
          },
          "id" : {
            "type" : "string"
          },
          "type" : {
            "type" : "string",
            "enum" : [
              "widgets"
            ]
          },
          "attributes" : {
            "type" : "object",
            "properties" : {
              "productName" : {
                "type" : "string"
              }
            },
            "required" : [
              "productName"
            ]
          }
        },
        "required" : [
          "attributes",
          "id",
          "relationships",
          "type"
        ]
      },
      "uniqueItems" : true
    }
  },
  "required" : [
    "included",
    "data"
  ]
}

Github

link
Stars: 0

Used By

Total: 0

Releases

Update to OpenAPIKit 0.11.0 - 2020-01-12 21:48:12

⚠️ Breaking Changes ⚠️ Version 0.11.0 of OpenAPIKit introduced breaking changes to the schema generation API that is extended by this library.

Update to OpenAPIKit 0.9.0 - 2019-12-16 00:24:03

⚠️ Potential for breaking changes downstream ⚠️

Update JSONAPI library to 3.0.0 - 2019-11-17 01:52:00

⚠️ Breaking Changes ⚠️ This includes breaking changes that update the JSONAPI+OpenAPI library to work with version 3.0.0 of the JSONAPI library.

OpenAPIKit version bump - 2019-11-04 01:55:09

Update OpenAPIKit version.

⚠️ Breaking Changes ⚠️ The new OpenAPIKit version contains breaking changes.

Update OpenAPIKit version - 2019-11-02 23:50:22

Update to newer OpenAPIKit version, fix playground pages.

⚠️ Breaking Changes ⚠️ The new OpenAPIKit version contains some breaking changes.

Update to JSONAPI v2 - 2019-09-27 05:22:14

Update version of JSONAPI, fix some bugs, remove dependency on JSONAPI-Arbitrary (was not actually a dependency and having it in the package broke usage of this library in downstream non-test executables).

Update OpenAPIKit version - 2019-09-07 21:11:52

⚠️ Breaking Changes ⚠️ This version of OpenAPIKit contains a number of breaking changes.

Update dependencies - 2019-08-25 00:40:30

Migrate to `OpenAPIKit` library. - 2019-07-28 05:03:01

⚠️ Breaking Changes ⚠️ Moved OpenAPI code out of this library and into its own package. The naming changed in the new package so this is a breaking change. The biggest name change is most things that used to be called JSONNode are now called JSONSchema.

This change also comes with much more complete test coverage of the OpenAPI code.

Update dependencies and mattpolzin/JSONAPI naming - 2019-07-03 16:13:51

⚠️ Breaking change ⚠️ In updating to the latest version of mattpolzin/JSONAPI so naming changes were required. These are mostly just types with "Entity" in their name getting changed to "ResourceObject" to better align with the naming in the JSON:API Spec.

Updated to Swift tools version 5.0 and Swift language version 5.0

Added required properties to OpenAPI parameter type. - 2019-02-01 06:20:30

Added "in" and "schema"/"content" properties to OpenAPI parameter type. These were not the only missing properties of that type, but they are the only ones required to create compliant OpenAPI documentation containing parameters.

First Pre-release outside of parent JSONAPI repo. - 2019-01-31 02:11:45

See https://github.com/mattpolzin/JSONAPI for a historical reference of this package's changes over time.