使用RAML描述API文檔信息的一些用法整理

来源:http://www.cnblogs.com/darrenji/archive/2016/02/18/5198524.html
-Advertisement-
Play Games

RAML是Restful API Modeling Language的縮寫,是用來描述API信息的文檔。 創建一個.raml尾碼的文件,用Atom打開。 基本用法 #%RAML 0.8 title: Book API baseUri: http://api.book.com/{version} ve


 

RAML是Restful API Modeling Language的縮寫,是用來描述API信息的文檔。

 

創建一個.raml尾碼的文件,用Atom打開。

 

基本用法

 

#%RAML 0.8
  title: Book API
  baseUri: http://api.book.com/{version}
  version: v1
  /users:
    /authors:
      /{authorname}:
    /books:
      get:
        queryParameters:
          author:
            displayName: Author
            type: string
            description: An author's full name
            example: Mary
            required: false
          publicationYear:
            displayName: Pub Year
            type: number
            description: The year released for the first time
            example: 1984
            required: false
          rating:
            displayName: Rating
            type: number
            description: Average rating
            required: false
          isBn:
            displayName: ISBN
            type: string
            minLength: 10
            example: 0321736079
      put:
        queryParameters:
          access_token:
            displayName: Access Token
            type: string
            description: Token giving you permission to make call
            required: true
      post:
      /{bookTitle}:
        get:
          description: Retrieve a specific book title
          responses:
            200:
              body:
                application/json:
                  example: |
                    {
                      "data":{
                        "id": "SbBGk",
                        "title": "its the title",
                        "descritpion": null
                      },
                      "success": true,
                      "status": 200
                    }

        put:
        delete:
        /author:
          get:
        /publiser:
          get:

 

以上,

● 類型/users:看作是resource,也就是以/開始,:結尾,而且resource是嵌套存在的
● queryParameters描述查詢字元串

 

接下來把.raml轉換成html格式,有一個開源的項目。

 

→ 參考:https://github.com/raml2html/raml2html
→ 全局安裝:npm i -g raml2html
→ .raml文件所在文件夾內打開命令視窗,輸入:raml2html example.raml > example.html

 

就是這麼個效果:

Body Parameters

 

POST請求,通常把參數放到body中傳遞,在RAML中如何描述呢?

 

在Body中的參數傳遞有很多方式,需要在Headers下的Content-Type中設置。Content-Type這個key可能的值包括:multipart/form-data, application/json, application/x-www-form-urlencoded等等。

 

1、通過multipart/form-data

 

/file-content:
  description: The file to be reproduced by the client
  get:
    description: Get the file content
    responses:
      200:
        body:
          binary/octet-stream:
            example:
              !include heybulldog.mp3
  post:
    description: |
       Enters the file content for an existing song entity.

       Use the "binary/octet-stream" content type to specify the content from any consumer (excepting web-browsers).
       Use the "multipart-form/data" content type to upload a file which content will become the file-content
    body:
      binary/octet-stream:
      multipart/form-data:
        formParameters:
          file:
            description: The file to be uploaded
            required: true
            type: file

 

以上,

● Content-Type能接受的類型是binary/octet-stream或multipart/form-data
● 對於multipart/form-data類型,鍵值數據放在了formParameters中
● !include heybulldog.mp3表示把heybulldog.mp3文件引入進來

 

2、通過JSON Shema

 

JSON Shema用來描述JSON格式。

 

為什麼需要JSON Schema呢?

 

舉個例子:

 

{
    "id":1,
    "name":"a green door",
    "price":12.50,
    "tags":["home", "green"]
}

 

我們可能會問:

● 什麼是id
● name欄位必須嗎
● price的值可以是0嗎
● tags所代表的數組元素是string類型嗎?


JSON Schema就是解決這些問題的。

 

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object"
}

 

以上,

● $schema表示當前JSON Shema所採用的版本
● type欄位是必須的,是object類型

 

接著,對id欄位約束。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "id": {
            "description": "The unique identifier for a product",
            "type": "integer"
        }
    },
    "required": ["id"]
}

 

對name欄位約束。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "id": {
            "description": "The unique identifier for a product",
            "type": "integer"
        },
        "name": {
            "description": "Name of the product",
            "type": "string"
        }
    },
    "required": ["id", "name"]
}

 

對price欄位約束。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "id": {
            "description": "The unique identifier for a product",
            "type": "integer"
        },
        "name": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
        }
    },
    "required": ["id", "name", "price"]
}

 

對tags欄位約束。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product",
    "description": "A product from Acme's catalog",
    "type": "object",
    "properties": {
        "id": {
            "description": "The unique identifier for a product",
            "type": "integer"
        },
        "name": {
            "description": "Name of the product",
            "type": "string"
        },
        "price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true
        },
        "tags": {
            "type": "array",
            "items": {
                "type": "string"
            },
            "minItems": 1,
            "uniqueItems": true
        }
    },
    "required": ["id", "name", "price"]
}

 


數組如何用JSON Schema描述呢?

 

[
    {
        "id": 2,
        "name": "An ice sculpture",
        "price": 12.50,
        "tags": ["cold", "ice"],
        "dimensions": {
            "length": 7.0,
            "width": 12.0,
            "height": 9.5
        },
        "warehouseLocation": {
            "latitude": -78.75,
            "longitude": 20.4
        }
    },
    {
        "id": 3,
        "name": "A blue mouse",
        "price": 25.50,
        "dimensions": {
            "length": 3.1,
            "width": 1.0,
            "height": 1.0
        },
        "warehouseLocation": {
            "latitude": 54.4,
            "longitude": -32.7
        }
    }
]

 

用JSON Shema描述就是這樣:

 

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product set",
    "type": "array",
    "items": {
        "title": "Product",
        "type": "object",
        "properties": {
            "id": {
                "description": "The unique identifier for a product",
                "type": "number"
            },
            "name": {
                "type": "string"
            },
            "price": {
                "type": "number",
                "minimum": 0,
                "exclusiveMinimum": true
            },
            "tags": {
                "type": "array",
                "items": {
                    "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
            },
            "dimensions": {
                "type": "object",
                "properties": {
                    "length": {"type": "number"},
                    "width": {"type": "number"},
                    "height": {"type": "number"}
                },
                "required": ["length", "width", "height"]
            },
            "warehouseLocation": {
                "description": "Coordinates of the warehouse with the product",
                "$ref": "http://json-schema.org/geo"
            }
        },
        "required": ["id", "name", "price"]
    }
}

 

RAML也用到了JSON Shema,就像這樣:

body:
  application/json:
    schema: |
      {
        "type": "object",
        "$schema": "http://json-schema.org/draft-03/schema",
        "id": "http://jsonschema.net",
        "required": true,
        "properties": {
          "songTitle": {
            "type": "string",
            "required": true
          },
          "albumId": {
            "type": "string",
            "required": true,
            "minLength": 36,
            "maxLength": 36
          }
        }
      }
    example: |
      {
        "songId": "550e8400-e29b-41d4-a716-446655440000",
        "songTitle": "Get Lucky",
        "albumId": "183100e3-0e2b-4404-a716-66104d440550"
      }

 

schemas

 

每個資源都有自己的schema,是否可以把所有資源的schema合併到同一個地方呢?

 

RAML提供了schemas欄位。

schemas:
 - song: |
    {
      "type": "object",
      "$schema": "http://json-schema.org/draft-03/schema",
      "id": "http://jsonschema.net",
      "required": true,
      "properties": {
        "songTitle": {
          "type": "string",
          "required": true
        },
        "albumId": {
          "type": "string",
          "required": true,
          "minLength": 36,
          "maxLength": 36
        }
      }
    }

 

按如下引用:

body:
  application/json:
    schema: song
    example: |
      {
        "songId": "550e8400-e29b-41d4-a716-446655440000",
        "songTitle": "Get Lucky",
        "albumId": "183100e3-0e2b-4404-a716-66104d440550"
      }

 

Resource Types資源類型

 

每個資源通有相似的部分,能否把這些相似的部分提取抽象出來呢?

 

假設有2個資源:/resources和/{resourceId}

#%RAML 0.8
title:

/resources:
  get:
  post:
  /{resourceId}:
    get:
    put:
    delete:

 

以上,resource大致可以分成針對集合和針對個體的,所以,在RAML中通過resourceTypes對資源進行分類,有這樣的表達方式:

resourceTypes:
  - collection:
      get:
      post:
  - collection-item:
      get:

 

於是collection類型可以寫成這樣:

resourceTypes:
  - collection:
      description: Collection of available <<resourcePathName>> in Jukebox.
      get:
        description: Get a list of <<resourcePathName>>.
        responses:
          200:
            body:
              application/json:
      post:
        description: |
          Add a new <<resourcePathName|!singularize>> to Jukebox.
        queryParameters:
          access_token:
            description: "The access token provided by the authentication application"
            example: AABBCCDD
            required: true
            type: string
        body:
          application/json:
            schema: <<resourcePathName|!singularize>>
        responses:
          200:
            body:
              application/json:
                example: |
                    { "message": "The <<resourcePathName|!singularize>> has been properly entered" }

 

以上,

● <<resourcePathName>>是占位符,類似表示songs
● 另外<<resourcePath>>是占位符,類似表示/songs
● <<resourcePathName|!singularize>>是占位符,類似表示song

● <<resourcePathName|!pluralize>>是占位符,類似表示songs


然後這樣使用:

/songs:
  type: collection
  get:
    queryParameters:
      songTitle:
        description: "The title of the song to search (it is case insensitive and doesn't need to match the whole title)"
        required: true
        minLength: 3
        type: string
        example: "Get L"
    responses:
      200:
        body:
          application/json:
            example: |
              "songs": [
                  {
                    "songId": "550e8400-e29b-41d4-a716-446655440000",
                    "songTitle": "Get Lucky"
                  },
                  {
                    "songId": "550e8400-e29b-41d4-a716-446655440111",
                    "songTitle": "Loose yourself to dance"
                  },
                  {
                    "songId": "550e8400-e29b-41d4-a716-446655440222",
                    "songTitle": "Gio sorgio by Moroder"
                  }
                  ]
  post:
    body:
      application/json:
          example: |
            {
              "songId": "550e8400-e29b-41d4-a716-446655440000",
              "songTitle": "Get Lucky",
              "albumId": "183100e3-0e2b-4404-a716-66104d440550"
            }

 

collection-item類型可以寫成這樣:

resourceTypes:
  - collection:
  ...

  - collection-item:
      description: Entity representing a <<resourcePathName|!singularize>>
      get:
        description: |
          Get the <<resourcePathName|!singularize>>
          with <<resourcePathName|!singularize>>Id =
          {<<resourcePathName|!singularize>>Id}
        responses:
          200:
            body:
              application/json:
          404:
            body:
              application/json:
                example: |
                  {"message": "<<resourcePathName|!singularize>> not found" }  

 

然後這樣使用:

/songs:
  ...
  /{songId}:
    type: collection-item
    get:
      responses:
        200:
          body:
            application/json:
              example: |
                {
                  "songId": "550e8400-e29b-41d4-a716-446655440000",
                  "songTitle": "Get Lucky",
                  "duration": "6:07",
                  "artist": {
                    "artistId": "110e8300-e32b-41d4-a716-664400445500"
                    "artistName": "Daft Punk",
                    "imageURL": "http://travelhymns.com/wp-content/uploads/2013/06/random-access-memories1.jpg"
                  },
                  "album": {
                    "albumId": "183100e3-0e2b-4404-a716-66104d440550",
                    "albumName": "Random Access Memories",
                    "imageURL": "http://upload.wikimedia.org/wikipedia/en/a/a7/Random_Access_Memories.jpg"
                  }
                }

 

以上,
● 在resourceTypes中的謂詞get,post等,可以在具體的resource中進行重新定義
● 在resrouce級別,通過type: collection-item或type: collection與resourceTypes對應

 

Parameters

 

以上,resourceTypes欄位所代表的是一個對集合和個體類型相同操作的一個封裝,在這些操作中,在這些請求響應中,有時需要通過example欄位來舉例,通常這樣寫:

example: |
    {
        ...
    }

或者

example: |
[
    {
    
    },
    {
    
    }
]

 

但在RAML中,為我們提供了<<exampleCollection>>和<<exampleItem>>占位符分別表示集合和個體。

resourceTypes:
  - collection:
      description: Collection of available <<resourcePathName>> in Jukebox.
      get:
        description: Get a list of <<resourcePathName>>.
        responses:
          200:
            body:
              application/json:
                example: |
                  <<exampleCollection>>
      post:
        description: |
          Add a new <<resourcePathName|!singularize>> to Jukebox.
        queryParameters:
          access_token:
            description: "The access token provided by the authentication application"
            example: AABBCCDD
            required: true
            type: string
        body:
          application/json:
            schema: <<resourcePathName|!singularize>>
            example: |
              <<exampleItem>>
        responses:
          200:
            body:
              application/json:
                example: |
                  { "message": "The <<resourcePathName|!singularize>> has been properly entered" }
  - collection-item:
      description: Entity representing a <<resourcePathName|!singularize>>
      get:
        description: |
          Get the <<resourcePathName|!singularize>>
          with <<resourcePathName|!singularize>>Id =
          {<<resourcePathName|!singularize>>Id}
        responses:
          200:
            body:
              application/json:
                example: |
                  <<exampleItem>>
          404:
            body:
              application/json:
                example: |
                  {"message": "<<resourcePathName|!singularize>> not found" }

 

在資源resource部分通常這樣調用:

/songs:
    type:
        collection:
            exampleCollection: |
                [
                    ...
                ]
    /{songId}:
        type:
            collection-item: 
                exampleItem: |
                {
                    ...
                }

 

具體來說,類似這樣:

/songs:
  type:
    collection:
      exampleCollection: |
        [
          {
            "songId": "550e8400-e29b-41d4-a716-446655440000",
            "songTitle": "Get Lucky"
          },
          {
            "songId": "550e8400-e29b-41d4-a716-446655440111",
            "songTitle": "Loose yourself to dance"
          },
          {
            "songId": "550e8400-e29b-41d4-a716-446655440222",
            "songTitle": "Gio sorgio by Morodera"
          }
        ]
      exampleItem: |
        {
          "songId": "550e8400-e29b-41d4-a716-446655440000",
          "songTitle": "Get Lucky",
          "albumId": "183100e3-0e2b-4404-a716-66104d440550"
        }
  get:
    queryParameters:
      songTitle:
        description: "The title of the song to search (it is case insensitive and doesn't need to match the whole title)"
        required: true
        minLength: 3
        type: string
        example: "Get L"
  /{songId}:
    type:
      collection-item:
        exampleItem: |
          {
            "songId": "550e8400-e29b-41d4-a716-446655440000",
            "songTitle": "Get Lucky",
            "duration": "6:07",
            "artist": {
              "artistId": "110e8300-e32b-41d4-a716-664400445500"
              "artistName": "Daft Punk",
              "imageURL": "http://travelhymns.com/wp-content/uploads/2013/06/random-access-memories1.jpg"
            },
            "album": {
              "albumId": "183100e3-0e2b-4404-a716-66104d440550",
              "albumName": "Random Access Memories",
              "imageURL": "http://upload.wikimedia.org/wikipedia/en/a/a7/Random_Access_Memories.jpg"
            }
          }

 

Includes

 

可以把一些example放到單獨的文件,然後通過!include關鍵字來引用這些文件。

 

/songs:
  type:
    collection:
      exampleCollection: !include jukebox-include-songs.sample
      exampleItem: !include jukebox-include-song-new.sample
  /{songId}:
    type:
      collection-item:
        exampleItem: !include jukebox-include-song-retrieve.sample

 

traits

 

如何描述查詢、排序、分頁呢?

 

traits:
  - searchable:
      queryParameters:
        query:
          description: |
            JSON array [{"field1","value1","operator1"},{"field2","value2","operator2"},...,{"fieldN","valueN","operatorN"}] <<description>>
          example: |
            <<example>>aml
            
  - orderable:
      queryParameters:
        orderBy:
          description: |
            Order by field: <<fieldsList>>
          type: string
          required: false
        order:
          description: Order
          enum: [desc, asc]
          default: desc
          required: false
  - pageable:
      queryParameters:
        offset:
          description: Skip over a number of elements by specifying an offset value for the query
          type: integer
          required: false
          example: 20
          default: 0
        limit:
          description: Limit the number of elements on the response
          type: integer
          required: false
          example: 80
          default: 10    

 

按如下使用這些trait。

/songs:
  type:
    collection:
      exampleCollection: !include jukebox-include-songs.sample
      exampleItem: !include jukebox-include-song-new.sample
  get:
    is: [
          searchable: {description: "with valid searchable fields: songTitle", example: "[\"songTitle\", \"Get L\", \"like\"]"},
          orderable: {fieldsList: "songTitle"},
          pageable
        ]

 

另外,schema也可以放到單獨的文件中,然後通過!include引用。

 

schemas:
 - song: !include jukebox-include-song.schema
 - artist: !include jukebox-include-artist.schema
 - album: !include jukebox-include-album.schema

 

resourceTypes也可以放到單獨的文件中:

resourceTypes: !include jukebox-includes-resourceTypes.inc

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ---恢復內容開始--- 系統 # uname -a #查看內核/操作系統/CPU信息 # head -n 1 /etc/issue #查看操作系統版本 # cat /proc/cpuinfo #查看CPU信息 # hostname #查看電腦名 # lspci -tv #列出所有PCI設備 #
  • 因為業務系統需求,需要對web服務作nginx代理,在不斷的嘗試過程中,簡單總結了一下常見的nginx代理配置。 1. 最簡反向代理配置 在http節點下,使用upstream配置服務地址,使用server的location配置代理映射。 upstream my_server { server 10
  • JDK1.4.2的安裝 Do you agree to the above license terms? [yes or no] yes Unpacking... tail: cannot open `+511' for reading: No such file or directory Chec
  • 作者: "@gzdaijie" 本文為作者原創,轉載請註明出處:http://www.cnblogs.com/gzdaijie/p/5194033.html 1.寫在前面 & 160;& 160;& 160;& 160;當你在Windows上安裝了一臺Linux的虛擬機,你想訪問Linux中的文件夾
  • 1.0 反序列化時的對象屬性類型定義錯誤. 字元串類型用整型接收.(導致一直反序列化失敗.) 2.0 HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(strUrl); myReq.Timeout = timeout; //ti
  • 很多情況下,列表顯示數據. 如果經過數據篩選或者搜索,依然是可以重用視圖的. 如何重用? ViewBag.Data=...;//保存數據. 或者, View(model);//傳model
  • UniformGrid:特殊的Grid,所有單元格相同尺寸。 Canvas:跟html5的canvas很像,也可以像winform那樣基於坐標佈局 Grid:網頁的table GridSplitter:Grid里的分隔符,可以拖動調整大小 //ShowsPreview="True" 拖拽不會立即調整...
  • 使用 HttpApplication 對象 ASP.NET 框架中的許多類都提供了許多很方便的屬性可以直接映射到 HttpContext 類中定義的屬性。這種交疊有一個很好的例子就是 HttpApplication,它就是全局應用類的基類,在下表中,你可以看到 HttpApplication 類中定
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...