NAME
SQL::Translator::Parser::OpenAPI - convert OpenAPI schema to SQL::Translator schema
SYNOPSIS
use SQL::Translator;
use SQL::Translator::Parser::OpenAPI;
my $translator = SQL::Translator->new;
$translator->parser("OpenAPI");
$translator->producer("YAML");
$translator->translate($file);
# or...
$ sqlt -f OpenAPI -t MySQL <my-openapi.json >my-mysqlschema.sql
# or, applying an overlay:
$ perl -MHash::Merge=merge -Mojo \
-e 'print j merge map j(f($_)->slurp), @ARGV' \
t/06-corpus.json t/06-corpus.json.overlay |
sqlt -f OpenAPI -t MySQL >my-mysqlschema.sql
DESCRIPTION
This module implements a SQL::Translator::Parser to convert a JSON::Validator::OpenAPI::Mojolicious specification to a SQL::Translator::Schema.
It uses, from the given API spec, the given "definitions" to generate tables in an RDBMS with suitable columns and types.
To try to make the data model represent the "real" data, it applies heuristics:
to remove object definitions considered non-fundamental; see "definitions_non_fundamental".
for definitions that have
allOf
, either merge them together if there is adiscriminator
, or absorb properties from referred definitionscreates object definitions for any properties that are an object
creates object definitions for any properties that are an array of simple OpenAPI types (e.g.
string
)creates object definitions for any objects that are
additionalProperties
(i.e. freeform key/value pairs), that are key/value rowsabsorbs any definitions that are in fact not objects, into the referring property
injects foreign-key relationships for array-of-object properties, and creates many-to-many tables for any two-way array relationships
ARGUMENTS
snake_case
If true, will create table names that are not the definition names, but instead the pluralised snake_case version, in line with SQL convention. By default, the tables will be named after simply the definitions.
PACKAGE FUNCTIONS
parse
Standard as per SQL::Translator::Parser. The input $data is a scalar that can be understood as a JSON::Validator specification.
defs2mask
Given a hashref that is a JSON pointer to an OpenAPI spec's /definitions
, returns a hashref that maps each definition name to a bitmask. The bitmask is set from each property name in that definition, according to its order in the complete sorted list of all property names in the definitions. Not exported. E.g.
# properties:
my $defs = {
d1 => {
properties => {
p1 => 'string',
p2 => 'string',
},
},
d2 => {
properties => {
p2 => 'string',
p3 => 'string',
},
},
};
my $mask = SQL::Translator::Parser::OpenAPI::defs2mask($defs);
# all prop names, sorted: qw(p1 p2 p3)
# $mask:
{
d1 => (1 << 0) | (1 << 1),
d2 => (1 << 1) | (1 << 2),
}
definitions_non_fundamental
Given the definitions
of an OpenAPI spec, will return a hash-ref mapping names of definitions considered non-fundamental to a value. The value is either the name of another definition that is fundamental, or or undef
if it just contains e.g. a string. It will instead be a reference to such a value if it is to an array of such.
This may be used e.g. to determine the "real" input or output of an OpenAPI operation.
Non-fundamental is determined according to these heuristics:
object definitions that only have one property (which the author calls "thin objects"), or that have two properties, one of whose names has the substring "count" (case-insensitive).
object definitions that have all the same properties as another, and are not the shortest-named one between the two.
object definitions whose properties are a strict subset of another.
OPENAPI SPEC EXTENSIONS
x-id-field
Under /definitions/$defname
, a key of x-id-field
will name a field within the properties
to be the unique ID for that entity. If it is not given, the id
field will be used if in the spec, or created if not.
This will form the ostensible "key" for the generated table. If the key used here is an integer type, it will also be the primary key, being a suitable "natural" key. If not, then a "surrogate" key (with a generated name starting with _relational_id
) will be added as the primary key. If a surrogate key is made, the natural key will be given a unique constraint and index, making it still suitable for lookups. Foreign key relations will however be constructed using the relational primary key, be that surrogate if created, or natural.
x-view-of
Under /definitions/$defname
, a key of x-view-of
will name another definition (NB: not a full JSON pointer). That will make $defname
not be created as a table. The handling of creating the "view" of the relevant table is left to the CRUD implementation. This gives it scope to use things like the current requesting user, or web parameters, which otherwise would require a parameterised view. These are not widely available.
x-artifact
Under /definitions/$defname/properties/$propname
, a key of x-artifact
with a true value will indicate this is not to be stored, and will not cause a column to be created. The value will instead be derived by other means. The value of this key may become the definition of that derivation.
x-input-only
Under /definitions/$defname/properties/$propname
, a key of x-input-only
with a true value will indicate this is not to be stored, and will not cause a column to be created. This may end up being merged with x-artifact
.
DEBUGGING
To debug, set environment variable SQLTP_OPENAPI_DEBUG
to a true value.
AUTHOR
Ed J, <etj at cpan.org>
LICENSE
Copyright (C) Ed J
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.