github.com/mmatczuk/gohan@v0.0.0-20170206152520-30e45d9bdb69/docs/schema.md (about)

     1  # Schema
     2  
     3  Developers defines resource model itself, and Gohan derives APIs, CLIs, and Docs from it. It is a so-called model-based development and conceptual difference from OpenAPI where developers define API.
     4  
     5  We will have a list of schemas to define a resource model.
     6  Each schema will have following properties.
     7  
     8  - id          -- resource id (must be unique)
     9  - singular    -- a singular form of the schema name
    10  - plural      -- plural form of the schema name
    11  - title       -- use the visible label of resource title
    12  - description -- a description of the schema
    13  - schema      -- JSON schema (see Spec on http://json-schema.org/)
    14  
    15  Schemas might also have any of the following optional properties.
    16  
    17  - parent    -- the id of the parent schema
    18  - on_parent_delete_cascade -- cascading delete when parent resource deleted
    19  - namespace -- resource namespace for grouping
    20  - prefix    -- resource path prefix
    21  - metadata  -- application specific schema metadata (object)
    22  - type      -- can be an abstract or empty string (see more in schema inheritance)
    23  - extends   -- list of base schemas
    24  
    25  ## Schema Inheritance
    26  
    27  Gohan supports mix-in of multiple schemas.
    28  Developers can make a schema as abstract schema specifying type=abstract. The developer can mix-in abstract schema.
    29  
    30  ```
    31    schemas:
    32    - description: base
    33      type: abstract
    34      id: base
    35      metadata:
    36        state_versioning: true
    37      plural: bases
    38      prefix: /v2.0
    39      schema:
    40        properties:
    41          description:
    42            description: Description
    43            default: ""
    44            permission:
    45            - create
    46            - update
    47            title: Description
    48            type: string
    49            unique: false
    50          id:
    51            description: ID
    52            permission:
    53            - create
    54            title: ID
    55            type: string
    56            unique: false
    57          name:
    58            description: Name
    59            permission:
    60            - create
    61            - update
    62            title: Name
    63            type: string
    64            unique: false
    65          tenant_id:
    66            description: Tenant ID
    67            permission:
    68            - create
    69            title: Tenant
    70            type: string
    71            unique: false
    72        propertiesOrder:
    73        - id
    74        - name
    75        - description
    76        - tenant_id
    77        type: object
    78      singular: base
    79      title: base
    80    - description: Network
    81      id: network
    82      extends:
    83      - base
    84      plural: networks
    85      schema:
    86        properties:
    87          providor_networks:
    88            description: Providor networks
    89            default: {}
    90            permission:
    91            - create
    92            - update
    93            properties:
    94              segmentaion_type:
    95                enum:
    96                - vlan
    97                - vxlan
    98                - gre
    99                type: string
   100              segmentation_id:
   101                minimum: 0
   102                type: integer
   103            title: Provider Networks
   104            type: object
   105            unique: false
   106          route_targets:
   107            description: Route targets
   108            default: []
   109            items:
   110              type: string
   111            permission:
   112            - create
   113            - update
   114            title: RouteTargets
   115            type: array
   116            unique: false
   117          shared:
   118            description: Shared
   119            permission:
   120            - create
   121            - update
   122            title: Shared
   123            type: boolean
   124            unique: false
   125            default: false
   126        propertiesOrder:
   127        - providor_networks
   128        - route_targets
   129        - shared
   130        type: object
   131      singular: network
   132      title: Network
   133  ```
   134  
   135  ## Metadata
   136  
   137  - nosync (boolean)
   138  
   139  We don't sync this resource for sync backend when this option is true.
   140  
   141  - state_versioning (boolean)
   142  
   143    whether to support state versioning <subsection-state-update>, defaults to false.
   144  
   145  - sync_key_template (string)
   146  
   147    configurable sync key path for schemas based on properties, for example: /v1.0/devices/{{device_id}}/virtual_machine/{{id}},
   148  
   149  - sync_plain (boolean)
   150  
   151    Write plain data, which is not JSON marshaled in the Gohan format, to the sync backend if true.
   152    By default, which is false, Gohan writes sync data in JSON with its own format. The format has `body` and `version` properties, then the value of the resource, which is also JSON object, is stored in the `body` property with escaping (e.g. `{"body": "{\"id\":1,\"property\":\"value\"}", "version": 1}`).
   153    However, this format is not always supported by your worker. Therefore you sometimes want Gohan to write sync data in a simpler way. This option allow you to get the body JSON data without encapsulation by Gohan (e.g. `{"id":1,"property":"value"}`).
   154    Note that when you use this option with `sync_property`, you can get the value of a specified property. For instance, when you provide `property` to `sync_property`, you will get `value` for the result. In this case, when the type of the value is `string`, Gohan doesn't marshal the value into a JSON string, which means you don't get `"value"` here. When the value is an array or an object, you will get a JSON marshalled string.
   155  
   156  - sync_property (string)
   157  
   158    Write only the value of the specified property to the sync backend.
   159  
   160  ## Properties
   161  
   162  We need to define properties of a resource using following parameters.
   163  
   164  - title
   165  
   166    User visible label of the property
   167  
   168  - format
   169  
   170    Additional validation hints for this property
   171    you can use defined attribute on http://json-schema.org/latest/json-schema-validation.html#anchor107
   172  
   173  - type
   174  
   175   Gohan supports standard JSON schema types including string, number, integer, boolean, array, object and combinations such as ["string", "null"]
   176    The Schema itself should be the object type.
   177  
   178  - default
   179  
   180    the default value of the property
   181  
   182  - enum
   183  
   184    You can specify list of allowed values
   185  
   186  - required
   187  
   188    List of required attributes to specified during creation
   189  
   190  
   191  Following properties are extended from JSON schema v4.
   192  
   193  - permission
   194  
   195    permission is a list of allowing actions for this property.
   196    valid values contains "create", "update".
   197    Gohan generates JSON schema for creating API and update API based on this value.
   198    Note that we can use this property for only first level properties.
   199  
   200  - unique boolean (unique key constraint)
   201  
   202  - indexed boolean
   203  
   204    Specify if index should be created in DB for given column 
   205  
   206  ## type string
   207  
   208  type string is for defining a string.
   209  You can use following parameters for a string.
   210  
   211  - minLength  max length of string
   212  - maxLength  min length of string
   213  - pattern    regexp pattern for this string
   214  - relation  (extended spec by Gohan)  define resource relation
   215  - relationColumn (extended spec by Gohan) define which column relation references (default: "id")
   216  - relation_property  (extended spec by Gohan) relation resource will be joined in list API request for this property name
   217  - on_delete_cascade  (extended spec by Gohan) cascading delete when related resource deleted
   218  
   219  eg.
   220  ```
   221          name:
   222            permission:
   223            - create
   224            - update
   225            title: Name
   226            type: string
   227            unique: false
   228  ```
   229  
   230  ## type boolean
   231  
   232  type boolean for boolean value
   233  
   234  eg.
   235  
   236  ```
   237          admin_state:
   238            permission:
   239            - create
   240            - update
   241            title: admin_state
   242            type: boolean
   243            unique: false
   244  ```
   245  
   246  ## type integer or type number
   247  
   248  type integer or type number for numeric properties.
   249  You can use following parameters to define valid range
   250  
   251  - maximum (number) and exclusiveMaximum (boolean)
   252  - minimum (number) and exclusiveMinimum (boolean)
   253  
   254  eg.
   255  
   256  ```
   257          age:
   258            permission:
   259            - create
   260            - update
   261            title: age
   262            type: number
   263            unique: false
   264  ```
   265  
   266  ## type array
   267  
   268  type array is for a defining list of elements
   269  
   270  ### items
   271  
   272    Only allowed for array type
   273    You can define element type on this property.
   274  
   275  eg.
   276  
   277  ```
   278          route_targets:
   279            default: []
   280            items:
   281              type: string
   282            permission:
   283            - create
   284            - update
   285            title: RouteTargets
   286            type: array
   287            unique: false
   288  ```
   289  
   290  ## type object
   291  
   292  Object type is for a defining object in the resources.
   293  Note that resource itself should be an object.
   294  Following parameters supported in the object type.
   295  
   296  - properties
   297  
   298    Only allowed for object type
   299    You can define properties of this object
   300  
   301  - propertiesOrder (extended parameter in gohan)
   302  
   303    Only allowed for object type
   304    You can define an ordering of properties using propertiesOrder for UI / CLI
   305  
   306  eg.
   307  
   308  ```
   309          providor_networks:
   310            default: {}
   311            permission:
   312            - create
   313            - update
   314            properties:
   315              segmentaion_type:
   316                enum:
   317                - vlan
   318                - vxlan
   319                - gre
   320                type: string
   321              segmentation_id:
   322                minimum: 0
   323                type: integer
   324            required:
   325            - segmentation_type
   326            - segmentation_id
   327            title: Provider Networks
   328            type: object
   329            unique: false
   330  ```
   331  
   332  Parent - child relationship
   333  -------------------------------
   334  
   335  Resources can be in a parent-child relationship. It means that the child resource has a foreign key to its parent, and utilized for UI and CLI.
   336  
   337  Gohan adds <parent>_id property automatically when Gohan loads schemas.
   338  
   339  eg.
   340  
   341  ```
   342          schemas:
   343          - description: Test Device
   344            id: test_device
   345            parent: ""
   346            singular: test_device
   347            plural: test_devices
   348            prefix: /v1.0
   349            schema:
   350              properties:
   351                name:
   352                  default: ""
   353                  permission:
   354                  - create
   355                  - update
   356                  title: Name
   357                  type: string
   358                  unique: false
   359                id:
   360                  permission:
   361                  - create
   362                  title: ID
   363                  type: string
   364                  format: uuid
   365              required:
   366              - segmentation_type
   367              - segmentation_id
   368              type: object
   369            title: Test Device
   370          - description: Test Physical Port
   371            id: test_port
   372            parent: "test_device"
   373            singular: test_port
   374            plural: test_ports
   375            prefix: /v1.0
   376            schema:
   377              properties:
   378                name:
   379                  default: ""
   380                  permission:
   381                  - create
   382                  - update
   383                  title: Name
   384                  type: string
   385                  unique: false
   386                id:
   387                  permission:
   388                  - create
   389                  title: ID
   390                  type: string
   391                  format: uuid
   392              type: object
   393            title: Test Physical Port
   394  ```
   395  
   396  ## Custom actions schema
   397  
   398  Resources can have custom actions, besides CRUD. To define them, add "actions" section and define JSON schema of allowed input format
   399  
   400  eg.
   401  
   402  ```
   403          schemas:
   404          - description: Server
   405            id: server
   406            parent: ""
   407            singular: server
   408            plural: server
   409            prefix: /v1.0
   410            schema:
   411              properties:
   412                name:
   413                  default: ""
   414                  permission:
   415                  - create
   416                  - update
   417                  title: Name
   418                  type: string
   419                  unique: false
   420                management_ip:
   421                  default: ""
   422                  format: ipv4
   423                  permission:
   424                  - create
   425                  - update
   426                  title: Management IP
   427                  type: string
   428                  unique: false
   429                id:
   430                  permission:
   431                  - create
   432                  title: ID
   433                  type: string
   434                  format: uuid
   435            actions:
   436              reboot:
   437                path: /:id/reboot
   438                method: POST
   439                input:
   440                  type: object
   441                  properties:
   442                    message:
   443                      type: string
   444                    delay:
   445                      type: string
   446                output: null
   447  ```
   448  
   449  Then, register extension to handle it, e.g.
   450  
   451  ```
   452    gohan_register_handler("action_reboot", function(context){
   453      // handle reboot in southbound
   454    });
   455  ```
   456  
   457  In order to query above action, POST to /v1.0/servers/:id/action with
   458  
   459  ```
   460    {
   461      "reboot": {
   462        "message": "Maintenance",
   463        "delay": "1h"
   464      }
   465    }
   466  ```
   467  
   468  ## Custom Isolation Level
   469  
   470  Developers can specify the transaction isolation level for API requests when Gohan is configured to connect MySQL database.
   471  The default setting is "read repeatable" for read operations and "serializable" for operations that modify the database (create, update, delete) and sync operation. (state_update, monitoring_update). The default for unspecified action is repeatable read.
   472  
   473  ```
   474      isolation_level:
   475        read:  REPEATABLE READ
   476        create:  SERIALIZABLE
   477        update: SERIALIZABLE
   478        delete: SERIALIZABLE
   479  ```
   480  
   481  ## OpenAPI / Swagger
   482  
   483  Gohan schema is supposed to define "Data Model," whereas OpenAPI/Swagger is supposed to define API.
   484  
   485  You can generate OpenAPI / Swagger file from Gohan schema so that you can afford swagger utility tools.
   486  
   487  ```
   488  
   489      gohan openapi --config-file etc/gohan.yaml
   490  
   491      # or you can customize template file using
   492  
   493      gohan openapi --config-file etc/gohan.yaml --template etc/templates/swagger.tmpl
   494  ```
   495  
   496  then you will get swagger.json.
   497  You can use this file for using swagger utility tools.
   498  
   499  For example, you can use go-swagger to generate go related code. (see http://goswagger.io/)
   500  
   501  ```
   502      $ swagger validate swagger.json
   503      The swagger spec at "swagger.json" is valid against swagger specification 2.0
   504  ```
   505  
   506  # API
   507  
   508  In this section, we show how we generate REST API based on a schema.
   509  
   510  "$plural", "$singular", "$prefix" and "$id" are read directly from schema,
   511  "$namespace_prefix" is computed using namespace information and might be empty if schema has no namespace specified.
   512  
   513  Note: An extension computes actual access URL for each resource and substitutes prefix property with it during schema listing calls. User can list resources using this URL and access a single instance of resource by prepending "/$id"
   514  suffix.
   515  
   516  ## List REST API
   517  
   518  List supports pagination by optional GET query parameters ``sort_key`` and ``sort_order``.
   519  
   520  Query Parameter   Style       Type           Default           Description
   521  sort_key          query       xsd:string     id                Sort key for results
   522  sort_order        query       xsd:string     asc               Sort order - allowed values are ``asc`` or ``desc``
   523  limit             query       xsd:int        0                 Specifies maximum number of results.
   524                                                                 Unlimited for non-positive values
   525  offset            query       xsd:int        0                 Specifies number of results to be skipped
   526  <parent>_id       query       xsd:string     N/A               When resources which have a parent are listed,
   527                                                                 <parent>_id can be specified to show only parent's children.
   528  <property_id>     query       xsd:string     N/A               filter result by property (exact match). You can use multiple filters.
   529  
   530  When specified query parameters are invalid, server will return HTTP Status Code ``400`` (Bad Request)
   531  with an error message explaining the problem.
   532  
   533  To make navigation easier, each ``List`` response contains additional header ``X-Total-Count``
   534  indicating number of all elements without applying ``limit`` or ``offset``.
   535  
   536  Example:
   537  GET http://$GOHAN/[$namespace_prefix/]$prefix/$plural?sort_key=name&limit=2
   538  
   539  Response will be
   540  
   541  HTTP Status Code: 200
   542  
   543  ```
   544  
   545    {
   546      "$plural": [
   547         {
   548           "attr1": XX,
   549           "attr2": XX
   550         }
   551      ]
   552    }
   553  
   554  ```
   555  
   556  ### Child resources access
   557  
   558  Gohan provides two paths for child resources.
   559  
   560  Full path
   561    To access a child resource in that way, we need to know all it parents.
   562  
   563    e.g. POST http://$GOHAN/[$namespace_prefix/]$prefix/[$ancestor_plural/$ancestor_id/]$plural
   564  
   565  Short path
   566  
   567    e.g. POST http://$GOHAN/[$namespace_prefix/]$prefix/$plural?$parent_id=<parent_id>
   568  
   569  ## GET
   570  
   571  Show REST API
   572  
   573  GET http://$GOHAN/[$namespace_prefix/]$prefix/$plural/$id
   574  
   575  Response will be
   576  
   577  HTTP Status Code: 200
   578  
   579  ```
   580    {
   581      "$singular": {
   582        "attr1": XX,
   583        "attr2": XX
   584      }
   585    }
   586  ```
   587  
   588  ## CREATE
   589  
   590  CREATE Resource REST API
   591  
   592  POST http://$GOHAN/[$namespace_prefix/]$prefix/$plural/
   593  
   594  Input
   595  
   596  Note that input JSON can only contain if you set "create" permission for this
   597  
   598  HTTP Status Code: 202
   599  
   600  ```
   601    {
   602      "$singular": {
   603        "attr1": XX,
   604        "attr2": XX
   605      }
   606    }
   607  ```
   608  
   609  Response will be
   610  
   611  ```
   612    {
   613      "$singular": {
   614        "attr1": XX,
   615        "attr2": XX
   616      }
   617    }
   618  ```
   619  
   620  ## Update
   621  
   622  Update Resource REST API
   623  
   624  PUT http://$GOHAN/[$namespace_prefix/]$prefix/$plural/$id
   625  
   626  Input
   627  
   628  Note that input JSON can only contain if you set "update" permission for this
   629  
   630  ```
   631    {
   632      "$singular": {
   633        "attr1": XX,
   634        "attr2": XX
   635      }
   636    }
   637  ```
   638  
   639  Response will be
   640  
   641  HTTP Status Code: 200
   642  
   643  ```
   644    {
   645      "$singular": {
   646        "attr1": XX,
   647        "attr2": XX
   648      }
   649    }
   650  ```
   651  
   652  ## DELETE
   653  
   654  Delete Resource REST API
   655  
   656  HTTP Status Code: 204
   657  
   658  DELETE http://$GOHAN/[$namespace_prefix/]$prefix/$plural/$id
   659  
   660  
   661  ## Custom Actions
   662  
   663  Run custom action on a resource
   664  
   665  POST http://$GOHAN/[$namespace_prefix/]$prefix/$plural/$id/$action_path
   666  
   667  Input
   668  
   669  Input JSON can only contain parameters defined in the input schema definition. It requires "$action" allow policy
   670  
   671  ```
   672    {
   673      "parameter1": XX,
   674      "parameter2": XX
   675    }
   676  ```
   677  
   678  Response will be
   679  
   680  HTTP Status Code: 200
   681  
   682  ```
   683    {
   684      "output1": XX,
   685      "output2": XX
   686    }
   687  ```