This extension for StarUML(http://staruml.io) supports the generation of GraphQL IDL schemas from UML models.
June 29th 2018:
Past:
Install this extension from StarUML's Extension Manager.
Tools > GraphQL > Generate Code...
)Select a folder where generated GraphQL source files will be placed.
file schema.gql will be generated at destination
Disclaimer: Neither StarUML nor this generator can enforce the limitations governed by the GraphQL expression language. It is of your responsibility to create data structures that will comply with the GraphQL specifications.
Let's start with the basics.
So let's start with a basic class generation. Here class attributes are given a type and a default value. We also made v3 a required field. Finally we added documentation here and there to demo what the generator does.
# name: GraphQL Generation Samples
# version: 1.0
# author Olivier Refalo
# copyright (c) Olivier Refalo
# Just a few comments to demo documentation generation.
type MyClass {
v1: String="helloworld"
v2: Int=5
# This field is required, it has a multiplicity=1
v3: String!
}
GraphQL offers a great way to implement custom behaviors using @directives. Using StarUML than can be modelled as Tags (if they need to be visually visible) or constraints. In the sample below, @const1 is not "visible"
type DirectiveClass {
name: String @fake(type: firstName) @const1(value1)
gender: String @examples(values: ["male", "female"])
}
Scalars and Enumerations are supported by StarUML's native Primitive and Enumeration types. Please ensure you use these native StarUML types in order to generate the expected artifacts.
scalar UUID
scalar Date
enum Enumeration1 {
L1
L2
L3
}
Union types are defined by using Dependencies. Typically Unions do not carry any attributes or relations. The generator will warn when it encounters such structure.
type Cat {
}
# test class doc
type Dog {
f1: String!
# test field doc
f2: String
toInvalidUnion: InvalidUnion
}
union AnimalUnionType = Cat | Dog
# WARNING: Attributes on union types is not GraphQL compliant, ignoring.
Important facts, associations are:
type Class3 {
toC4: [Class4]!
}
type Class4 {
name: String
gender: String
toC3: Class3!
}
type Class1 {
query: [Class2]!
mutation: Class5
}
type Class2 {
query: Class1
}
type Class5 {
}
type Team {
subteams: [Team]
parent: Team
builds: [Airplan]!
teams: [Employee]!
}
type Airplan {
toComponent: [Component]!
}
type Employee {
members: [Team]
}
type Component {
toAirplan: Airplan!
subassembly: [Component]
assembly: [Component]
}
Unlike GraphQL syntax, there is no need to repeat the attribute definition across the hierarchy. The generator takes care of it, Neat!
type Vehicule {
id: ID
}
type Car extends PassengerVehicule {
noOfDoors: Int
nrOfPasssengers: Int!
id: ID
}
type Truck extends TransportationVehicule {
numberOfCountainers: Int
loadCapacity: Int
id: ID
}
type TransportationVehicule extends Vehicule {
loadCapacity: Int
id: ID
}
type PassengerVehicule extends Vehicule {
nrOfPasssengers: Int!
id: ID
}
type Bike extends PassengerVehicule {
saddleHeight: Float
nrOfPasssengers: Int!
id: ID
}
Here we use InterfaceRealization to implement an interface in a new class. Note how the child attributes are automatically inherited from the parent interface.
type Bar implements Foo {
is_bar: String
is_foo: String
}
type Baz implements Foo, Goo {
is_baz: String
is_foo: String
is_goo: String
}
interface Foo {
is_foo: String
}
interface Goo {
is_goo: String
}
Finally a example showing interface extension.
type Class1 {
r1: Class2
}
type Class2 {
}
type ClassB {
}
type ClassA {
r2: ClassB
}
interface I1 {
f1: Int
i1ToC22: ClassA
i1ToC1: Class1
}
interface I2 extends I1 {
f1: Int
i1ToC22: ClassA
i1ToC1: Class1
}
type RootMutation {
createTodo(input: CreateTodoInput!) : CreateTodoPayload
toggleTodoCompleted(input: ToggleTodoCompletedInput!) : ToggleTodoCompletedPayload
}
schema {
mutation: RootMutation!
}
# `id` is generated by the backend, and `completed` is automatically set to false
input CreateTodoInput {
text: String!
}
type Todo {
id: ID
text: String
completed: Boolean
}
type CreateTodoPayload {
todo: Todo!
}
input ToggleTodoCompletedInput {
id: ID!
}
type ToggleTodoCompletedPayload {
todo: Todo
}
The following rules apply during generation.
union
stereotype converted to an union type, using dependency connections to related types.input
stereotype converted to an input type.schema
stereotype converted to a GraphQL schema.name
property to field identifier.type
property to field type, defaults to String.multiplicity
property to array type and/or required constraint.name
property to method identifier.multiplicity
property to array type and/or required constraint.direction
= return
to return type of method..ts
file)name
property to field identifier.type
property to field type.multiplicity
property to array type and required constraint.Cardinality property | => Generation |
---|---|
0..1 | field |
1 | field! |
n n>1 | [field!] |
0.. or | [field] |
1..* | [field!] |
Ensure Preference's option is turned on, use starUML documentation area. The generator will pick it up.
A Union is a class with a union stereotype, types are referenced via a Dependency relationship
Use gqlschema from npm's gql-tools
That StartUML default interface rendering. Right click on the interface, from the context menu, pick Format > Stereotype display > Decorations and labels
Cardinality property | => Generation |
---|---|
1 | field! |
n n>1 | [field!] |
1..* | [field!] |
StarUML.app/Contents/www/extensions/dev
My name is Olivier Refalo, author behind this StarUML extension. I am an Innovator, a Digital transformer, a skilled Architect, a Leader and an Entrepreneur.
Over the years I grew extensive knowledge around data modeling, reactive technologies, business processes, integrations and enterprise architecture. Lately I grew my technical skills around GraphQL which I see as an elegant way to solve the "middleware mess" with an inversion of control approach.
I believe in open source as a way to drive innovations and share knowledge, this project is yet another way to contribute back to the community. With that said, if you do use this project, please consider:
Thank you
Licensed under GPLv3