notEthan / jsi

JSI: JSON Schema Instantiation in Ruby
Other
23 stars 1 forks source link

How to use jsi with OpenAPI #349

Closed vivien closed 2 days ago

vivien commented 3 weeks ago

Hi there -- I'm trying to use jsi with a schema described as part of an OpenAPI specs: https://github.com/structurizr/json/blob/master/structurizr.yaml to get ruby OOP to access the data. An example of json data for this spec is https://structurizr.com/json. Should I be using Scorpio for this?

notEthan commented 3 weeks ago

Hi Vivien. Yes, Scorpio is the tool to use for OpenAPI (it integrates closely with JSI). You can use it as an API client, which will automatically instantiate response objects (like that API's workspace) as instances of their schemas. You can also use its representation of an OpenAPI document, and the schemas it contains, to instantiate objects more directly, if you don't need it to be an API client. Happy to help if you let me know what you want to do with it.

vivien commented 3 weeks ago

Thank you Ethan! My goal is to export a Structurizr workspace from its JSON format to asciidoc(tor) documentation pages. For example, I'll use an element name as a title, embed its various views (diagrams) as plantuml blocks, etc. The workspace is split in a model (the various nested block components description) and the views (the diagrams). As you can see in the JSON example, a view might contain a softwareSystemId key which corresponds to a SoftwareSystem object, as per the JSON schema. so I figured it would be easier to have such objects accessible from Ruby to extract the data I need and format a workspace to the output I need, without writing custom classes to match the schema myself. I can provide a bigger workspace example if that helps!

notEthan commented 3 weeks ago

That sounds pretty interesting, sounds like a good fit for JSI. Scorpio is useful for representing the OpenAPI there. The approach I'd start with would look like:

setup:

require 'scorpio'
module Structurizr
  OAD = Scorpio::OpenAPI::Document.from_instance(YAML.safe_load(Faraday.get('https://raw.githubusercontent.com/structurizr/json/refs/heads/master/structurizr.yaml').body))

  # name any modules desired
  Workspace = OAD.components.schemas["Workspace"].jsi_schema_module
  Documentation = OAD.components.schemas["Documentation"].jsi_schema_module
  Model = OAD.components.schemas["Model"].jsi_schema_module
  SoftwareSystem = OAD.components.schemas["SoftwareSystem"].jsi_schema_module

  module Workspace
    def to_asciidoc
      '...'
    end
  end
end

instantiation:

ws = Structurizr::Workspace.new_jsi(JSON.parse(%q({
  "documentation": {},
  "model": {
    "softwareSystems": [
      {"documentation": {}}
    ]
  }
})))
#=> #{<JSI (Structurizr::Workspace)>
#  "documentation" => #{<JSI (Structurizr::Documentation)>},
#  "model" => #{<JSI (Structurizr::Model)>
#    "softwareSystems" => #[<JSI (Structurizr::Model.properties["softwareSystems"])>
#      #{<JSI (Structurizr::SoftwareSystem)>
#        "documentation" => #{<JSI (Structurizr::Documentation)>}
#      }
#    ]
#  }
#}
notEthan commented 2 days ago

I hope that worked out for you, would be happy to hear if so (or if not). Closing this for now.