我试图将MT的API转换为GraphQL(正在进行中)

這是2019年可移動式類型(Movable Type)的聖誕日曆第三天的文章。
順便說一下,我正在12月9日星期一寫下這篇文章。 真相是,我已經完全忘記了註冊和註冊日期,並且收到了反饋後匆忙寫這篇文章。非常抱歉自己註冊後忘記了。。。

我尝试将MT的API转换为GraphQL(进行中)。

大家知道GraphQL吗?它在2015年左右发布,被Facebook等大公司开发作为替代RestAPI的方法,并被GitHub、Airbnb、Netflix等大公司采用,成为了讨论的话题。顺便一提,我的了解只限于它是个方便的东西,所以我一直想尝试一下,这次借着AdventCalendar的机会,我把MT的API转化成了GraphQL并学习了一下。

然而,’途中’這個詞的意思是GraphQL本身的理解還不夠深入,而且覆蓋MT的所有API需要極長的時間,所以目前只處於入門階段。
我們將繼續進行開發,希望您能以溫和的態度看待這次的導入部分。
(歡迎提出建議和指正)

GraphQL是什么?

把GraphQL简单解释一下:它是一种API。

除了MT的API之外,至今为止多数都是使用被称为REST(RESTful)的方式实现的。

休息 (xiū xí)

    • リソース(取得できる結果)ごとにURLがある

 

    • URLによって得られる結果が決まっている

 

    情報の操作(取得、作成、更新、削除)は全てHTTPメソッド(GET、POST、PUT、DELETE)

如果使用MT的Data API来获取内容数据,格式如下:
MT ContentData API 参考文档

[获取] http://example.com/mt/mt-data-api.cgi/v4/sites/{site_id}/contentTypes/{content_type_id}/data

那么,得到的结果将以以下形式呈现。(引用自参考资料)

{
  "totalResults": 1,
  "items": [
    {
      "author": {
        "displayName": "Hello, world!",
        "id": 1,
        "userpicUrl": "Hello, world!"
      },
      "basename": "Hello, world!",
      "blog": {
        "id": 1
      },
      "createdDate": "Hello, world!",
      "data": [
        {
          "data": "Hello, world!",
          "id": 1,
          "label": "Hello, world!",
          "type": "Hello, world!"
        }
      ],
      "date": "Hello, world!",
      "id": 1,
      "label": "Hello, world!",
      "modifiedBy": {
        "displayName": "Hello, world!",
        "id": 1,
        "userpicUrl": "Hello, world!"
      },
      "modifiedDate": "Hello, world!",
      "status": "Hello, world!",
      "unpublishedDate": "Hello, world!",
      "updatable": true
    }
  ]
}

如果您未从管理画面更新,访问上述URL将返回相同的结果。

每个资源都有一个URL作为其特征,因此只能通过上述URL获取ContentData的信息。
如果想获取网站名称或内容类型名称等信息,则需要再通过另一个URL获取。

当使用API动态获取信息并在屏幕上显示时,
如果屏幕只需要ContentData的信息就足够,那就没有问题。

然而通常情况下,我们需要了解是哪个网站的内容数据,以及是哪种类型的内容数据,因此需要更多的信息。在这种情况下,使用RestAPI需要进行多次访问。

    1. 获取网站信息(/sites/{site_id})

 

    1. 获取内容类型信息(/sites/{site_id}/contentTypes/{content_type_id})

 

    获取内容数据(/sites/{site_id}/contentTypes/{content_type_id}/data/{content_data_id})

使用者一方也需要思考在哪个终点会返回什么结果才能使用,而开发者需要根据想要获取的结果变化而不断增加终点。

另外,对于破坏性变更(例如获取结果发生变化)的终端点,则会将版本号从/v4/更改为/v5等,同时保证以前的终端点仍可获取结果,这也是一个特点之一。

如果场景在某种情况下发生了一个字段的增加或减少,我们会更新版本号。

由于这些原因,终端点数量不断增加,每次都需要重新制作手册,需要进行发布,这变得非常繁琐。

GraphQL是一种用于API开发的查询语言。

GraphQL在解决上述REST的问题时,具有以下特点:

    • URL(エンドポイント)は一つ

 

    • 取得したいデータをアクセス時にbodyに送る(POST送信)

 

    情報の操作(取得、作成、更新、削除)はbodyないで書く(Query、Mutation)

为了学习GraphQL,我将MT的API的一部分转化为了GraphQL。
我尽力以简单易懂的方式实现了它(尽管我的知识有限)。

[帖子] http://example.com/mt/plugins/GraphQL/graphql.cgi

身体

{ 
  sites { 
    name
  }
  contentdata(Filter: {siteID: 1}) {
    id
    label
  }
}

得到的JSON结果如下所示。

{
    "data": {
        "contentdata": [
            {
                "id": "48",
                "label": "Now burning pamphlets at this very."
            },
            {
                "id": "49",
                "label": "That they were awake was the."
            },
            {
                "id": "50",
                "label": "Now hanging a fair faces trod!"
            }
        ],
        "sites": [
            {
                "name": "test"
            },
            {
                "name": "test1"
            }
        ]
    }
}

在结果部分,数据中包含了”contentdata”和”sites”。
“contentdata”是指内容数据的信息,”sites”是指网站的信息,
可以在一个请求中获取到内容数据和网站的信息。

我接下来将尝试获取网站的所有页面和其中包含的内容数据。

[POST] http://example.com/mt/plugins/GraphQL/graphql.cgi

[发送] http://example.com/mt/plugins/GraphQL/graphql.cgi

身体

{ 
  sites { 
    name
    contentdata {
      label
    }
  }
}

得到的JSON结果如下所示


{
    "data": {
        "sites": [
            {
                "contentdata": [
                    {
                        "label": "Now burning pamphlets at this very."
                    },
                    {
                        "label": "That they were awake was the."
                    },
                    {
                        "label": "Now hanging a fair faces trod!"
                    }
                ],
                "name": "test"
            },
            {
                "contentdata": [
                    {
                        "label": "test"
                    },
                    {
                        "label": "test"
                    }
                ],
                "name": "test1"
            }
        ]
    }
}

有了这个JSON,可以显示每个网站的内容数据列表等。

你可能注意到了,实际上在返回的结果中,第一个样本的内容数据包含id和label,
而第二个样本只返回label。

特征的第二个部分是在访问时将想要获取的数据发送到请求的body中。

以下是一个选项的中文释义:

第一个

{ 
  sites { 
    name
  }
  contentdata(Filter: {siteID: 1}) {
    id
    label
  }
}

在contentdata中写入了id和label,因此返回的结果中也有id和label。

第二个是

{ 
  sites { 
    name
    contentdata {
      label
    }
  }
}

由于 contentdata 中只写了标签,所以只会返回标签作为结果。

在Rest中,针对每个终端点指定的结果都会返回,所以用户端(前端)需要接收不必要的数据。
* 附注:对于MT,可以通过在内容数据列表获取API中添加字段来筛选所需的字段,但除非有这样的便利实现,否则将返回实施方指定的所有字段。
在GraphQL中,用户可以通过编写所需的字段来接收自己所需的数据。

总结

这次只介绍了GraphQL的浅显部分,
还有很多特点和方便之处,
但因为我的学习不足,无法达到能够向他人解释的程度,就到这里为止。

我想写一些关于我制作插件时使用的模块以及我遇到的困难,但是我自己还没有归纳整理好,所以希望将来有机会再写。

如果你以前使用过MT的API,但不知道GraphQL是什么,我希望你能稍微了解一下,嗯,这样的话我会很高兴。

广告
将在 10 秒后关闭
bannerAds