From 29ec6c29e023fbcaa2e8cc3ee5d4812fd517fccb Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 03:40:08 +0200 Subject: [PATCH 01/10] feat: initial work towards a PoB API contract --- docs/APIContract.md | 43 ++++++++++++ src/Classes/APIContractBuilds.lua | 108 ++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 docs/APIContract.md create mode 100644 src/Classes/APIContractBuilds.lua diff --git a/docs/APIContract.md b/docs/APIContract.md new file mode 100644 index 0000000000..3e4b6a93e5 --- /dev/null +++ b/docs/APIContract.md @@ -0,0 +1,43 @@ +# Versions + +So far there is only one version + +The base URL for an API should be: _baseURL_/_apiVersion_/ meaning even something such as sometestbuildsforpoe.gg/something/a/b/c/ would be valid as a base URL, as long as it has afterwards the per version required endpoints. + +## Metadata Endpoint + +In order to provide a consistent API a metadata endpoint should be provided under _baseURL_/.well-known/pathofbuilding this endpoint should provide information about the API and the version of the API. +Furthermore this may allow having custom endpoints for the API. + +## Version 1 + +### Response and Request types + +#### BuildInfo + +| Field | Type | Description | +| ------------ | ------- | ----------------------------------- | +| pobdata | string | The Path of Building data | +| name | string | The name of the build | +| lastModified | integer | The last modification timestamp | +| buildId | string | The unique identifier for the build | + +### Endpoints + +
+ GET /v1/builds (Lists multiple builds) + +#### Parameters + +| name | type | data type | description | +| ---- | -------- | --------- | ------------------- | +| page | optional | integer | Used for pagination | + +#### Responses + +| http code | content-type | response | +| --------- | ------------------ | ------------------ | +| `200` | `application/json` | `BuildInfo object` | + +
+ diff --git a/src/Classes/APIContractBuilds.lua b/src/Classes/APIContractBuilds.lua new file mode 100644 index 0000000000..26188a74a3 --- /dev/null +++ b/src/Classes/APIContractBuilds.lua @@ -0,0 +1,108 @@ +-- Path of Building +-- +-- Class: API Contract Builds +-- API contract proposal for builds +-- + +local dkjson = require "dkjson" + + +---@enum EndpointType +local EndpointType = { + REST = 0, + CSV = 1 +} + +--example for REST vs CSV +-- REST: +-- {"baseUrl": "https://mypoebuilds.gg/pob-api/", "name": "MyPoEBuilds REST", "endpointType": 0, "fallbackVersion": 1} +-- baseUrl meaning the actual baseUrl +-- CSV: +-- {"baseUrl": "https://mypoebuilds.gg/pob-builds.csv", "name": "MyPoEBuilds CSV", "endpointType": 1, "fallbackVersion": 1} +-- baseUrl means here the full URL to the actual file or endpoint that returns a CSV formatted file from a GET endpoint + +--- This is the required information from the enduser +---@class APISourceInfo +---@field name string +---@field baseUrl string +---@field endpointType EndpointType +---@field fallbackVersion integer + +--- This data should be returned by the source +---@class BuildInfo +---@field pobdata string +---@field name string +---@field lastModified integer +---@field buildId string + +--- This data is saved internally for caching +---@class BuildInfoCache +---@field pobdata string +---@field name string +---@field lastModified integer +---@field buildId string +---@field sourceName string + +---This primarily exists for the lua language server +---@param buildInfo BuildInfo +---@param source APISourceInfo +---@return BuildInfoCache +local function buildInfoToCache(buildInfo, source) + return { + pobdata = buildInfo.pobdata, + name = buildInfo.name, + lastModified = buildInfo.lastModified, + buildId = buildInfo.buildId, + sourceName = source.name + } +end + +---@class APIContractBuilds +---@field buildList BuildInfoCache[] +local APIContractBuilds = newClass("APIContractBuilds", + function(self) + self.buildList = {} + end +) + +-- Switch case for GET Endpoint for Builds +local getBuildVersions = { + [0] = function(...) return APIContractBuilds:GetBuildsVersion1(...) end, +} + +---comments +---@param path string +---@param source APISourceInfo +function APIContractBuilds:GetBuilds(path, source) + local builds = getBuildVersions[source.fallbackVersion](path, source.endpointType) +end + +---@param source APISourceInfo +function APIContractBuilds:GetAPICapabilities(source) + -- TODO: Which features are supported? + -- What is the latest version that is supported? + -- Which endpoints are supported + -- Is Querying supported? (CSV won't support this probably) +end + +---@param response table | BuildInfo[] +---@param errMsg any +---@param source APISourceInfo +function APIContractBuilds:BuildsVersion1Callback(source, response, errMsg) + for _, build in ipairs(response) do + -- source and buildId will be used as a caching key + -- to avoid buildId collissions + self.buildList[common.sha1(source.name + "-" + build.buildId)] = buildInfoToCache(build, source) + end +end + +---Version 1 of the API Contract for Builds +---@param path string +---@param source APISourceInfo +function APIContractBuilds:GetBuildsVersion1(path, source) + if source.endpointType == EndpointType.REST then + launch:DownloadPage(source.baseUrl + path, function(...) + self:BuildsVersion1Callback(source, ...) + end, {}) + end +end From e30825bfa8a4a1d0859fcd89bec765d35ffb3927 Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 10:52:35 +0200 Subject: [PATCH 02/10] docs: extended proposal for endpoints --- docs/APIContract.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/APIContract.md b/docs/APIContract.md index 3e4b6a93e5..0d558e8b44 100644 --- a/docs/APIContract.md +++ b/docs/APIContract.md @@ -9,6 +9,11 @@ The base URL for an API should be: _baseURL_/_apiVersion_/ meaning even somethin In order to provide a consistent API a metadata endpoint should be provided under _baseURL_/.well-known/pathofbuilding this endpoint should provide information about the API and the version of the API. Furthermore this may allow having custom endpoints for the API. +| Feature | Field | Type | Description | +| ---------------- | ------------- | ---- | --------------------------------------------------------------------------------- | +| League Filtering | league_filter | bool | This can be used to indicate whether the API supports filtering based on leagues | +| Gem Filtering | gem_filter | bool | This can be used to indicate whether the API supports filtering based on gems | + ## Version 1 ### Response and Request types @@ -28,10 +33,29 @@ Furthermore this may allow having custom endpoints for the API. GET /v1/builds (Lists multiple builds) #### Parameters +> Query Parameters + +| name | type | data type | description | +| ------ | -------- | --------- | --------------------------------------- | +| page | optional | integer | Used for pagination | +| league | optional | string | Used to limit builds to a league | +| gems | optional | string | Used to limit builds with specific gems | + +##### League + +The values should be matching what Grinding Gear Games will be using for the teaser part of the website, such as: _https://www.pathofexile.com/settlers_ or _https://www.pathofexile.com/affliction_. This allows for easier mapping of the data as neither PoB nor the API will be required to wait for either party. + +These links are generally available via poewiki see: https://www.poewiki.net/wiki/Necropolis_league _Official Page_. + +Example values: -| name | type | data type | description | -| ---- | -------- | --------- | ------------------- | -| page | optional | integer | Used for pagination | +| Patch | League | value | url | +| ----- | ---------------------- | ---------- | -------------------------------------- | +| 3.25 | Settlers of Kalguur | settlers | https://www.pathofexile.com/settlers | +| 3.24 | Necropolis | necropolis | https://www.pathofexile.com/necropolis | +| 3.23 | Affliction | affliction | https://www.pathofexile.com/affliction | +| 3.22 | Trial of the Ancestors | ancestor | https://www.pathofexile.com/ancestor | +| 3.4 | Delve | delve | https://www.pathofexile.com/delve | #### Responses From c29ddaf47cb5199f333cf4a27e730d0ea86f9ef1 Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 11:18:48 +0200 Subject: [PATCH 03/10] feat: api capabilities and matching APIContract.md --- src/Classes/APIContractBuilds.lua | 58 +++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/Classes/APIContractBuilds.lua b/src/Classes/APIContractBuilds.lua index 26188a74a3..be953ee96c 100644 --- a/src/Classes/APIContractBuilds.lua +++ b/src/Classes/APIContractBuilds.lua @@ -21,7 +21,7 @@ local EndpointType = { -- {"baseUrl": "https://mypoebuilds.gg/pob-builds.csv", "name": "MyPoEBuilds CSV", "endpointType": 1, "fallbackVersion": 1} -- baseUrl means here the full URL to the actual file or endpoint that returns a CSV formatted file from a GET endpoint ---- This is the required information from the enduser +--- APISourceInfo is the configurated data for a source from the enduser ---@class APISourceInfo ---@field name string ---@field baseUrl string @@ -43,9 +43,18 @@ local EndpointType = { ---@field buildId string ---@field sourceName string +--- API Capabilities returned by the source or defaulted to APISourceInfo +---@class APICapabilities +---@field name string +---@field fallbackVersion integer +---@field endpointType EndpointType +---@field baseAPIPath string +---@field league_filter boolean +---@field gem_filter boolean + ---This primarily exists for the lua language server ---@param buildInfo BuildInfo ----@param source APISourceInfo +---@param source APICapabilities ---@return BuildInfoCache local function buildInfoToCache(buildInfo, source) return { @@ -58,10 +67,12 @@ local function buildInfoToCache(buildInfo, source) end ---@class APIContractBuilds ----@field buildList BuildInfoCache[] +---@field buildList table +---@field apiCapabilities table local APIContractBuilds = newClass("APIContractBuilds", function(self) self.buildList = {} + self.apiCapabilities = {} end ) @@ -83,13 +94,38 @@ function APIContractBuilds:GetAPICapabilities(source) -- What is the latest version that is supported? -- Which endpoints are supported -- Is Querying supported? (CSV won't support this probably) + + if source.endpointType ~= EndpointType.REST then + return + end + + launch:DownloadPage(source.baseUrl + "/.well-known/pathofbuilding", + function(...) return APIContractBuilds:APICapabilitiesCallback(source, ...) end, {}) end ----@param response table | BuildInfo[] +---@param response table ---@param errMsg any ---@param source APISourceInfo +function APIContractBuilds:APICapabilitiesCallback(source, response, errMsg) + local parsedResponse = dkjson.decode(response.body) + ---@cast parsedResponse APICapabilities + if errMsg or not parsedResponse.baseAPIPath then + parsedResponse.baseAPIPath = source.baseUrl + end + parsedResponse.name = source.name + parsedResponse.fallbackVersion = source.fallbackVersion + parsedResponse.endpointType = source.endpointType + + self.apiCapabilities[source.name] = parsedResponse +end + +---@param response table +---@param errMsg any +---@param source APICapabilities function APIContractBuilds:BuildsVersion1Callback(source, response, errMsg) - for _, build in ipairs(response) do + local parsedResponse = dkjson.decode(response.body) + ---@cast parsedResponse BuildInfo[] + for _, build in ipairs(parsedResponse) do -- source and buildId will be used as a caching key -- to avoid buildId collissions self.buildList[common.sha1(source.name + "-" + build.buildId)] = buildInfoToCache(build, source) @@ -98,11 +134,13 @@ end ---Version 1 of the API Contract for Builds ---@param path string ----@param source APISourceInfo +---@param source APICapabilities function APIContractBuilds:GetBuildsVersion1(path, source) - if source.endpointType == EndpointType.REST then - launch:DownloadPage(source.baseUrl + path, function(...) - self:BuildsVersion1Callback(source, ...) - end, {}) + if source.endpointType ~= EndpointType.REST then + return end + + launch:DownloadPage(source.baseAPIPath + path, function(...) + self:BuildsVersion1Callback(source, ...) + end, {}) end From 0bad178fa85db9e171ca446d8ce18db1fc8d6481 Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 11:28:44 +0200 Subject: [PATCH 04/10] fix: incorrect API call and general cleanup --- src/Classes/APIContractBuilds.lua | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Classes/APIContractBuilds.lua b/src/Classes/APIContractBuilds.lua index be953ee96c..a3f45a2a88 100644 --- a/src/Classes/APIContractBuilds.lua +++ b/src/Classes/APIContractBuilds.lua @@ -36,6 +36,7 @@ local EndpointType = { ---@field buildId string --- This data is saved internally for caching +--- Save this to disk for temporary local caching if required/desired ---@class BuildInfoCache ---@field pobdata string ---@field name string @@ -48,11 +49,11 @@ local EndpointType = { ---@field name string ---@field fallbackVersion integer ---@field endpointType EndpointType ----@field baseAPIPath string ----@field league_filter boolean ----@field gem_filter boolean +---@field baseAPIPath? string +---@field league_filter? boolean +---@field gem_filter? boolean ----This primarily exists for the lua language server +--- This primarily exists for the lua language server ---@param buildInfo BuildInfo ---@param source APICapabilities ---@return BuildInfoCache @@ -81,15 +82,14 @@ local getBuildVersions = { [0] = function(...) return APIContractBuilds:GetBuildsVersion1(...) end, } ----comments ----@param path string +--- Gets the builds from the source ---@param source APISourceInfo -function APIContractBuilds:GetBuilds(path, source) - local builds = getBuildVersions[source.fallbackVersion](path, source.endpointType) +function APIContractBuilds:GetBuilds(source) + getBuildVersions[source.fallbackVersion](source.endpointType) end ---@param source APISourceInfo -function APIContractBuilds:GetAPICapabilities(source) +function APIContractBuilds:UpdateAPICapabilities(source) -- TODO: Which features are supported? -- What is the latest version that is supported? -- Which endpoints are supported @@ -103,6 +103,7 @@ function APIContractBuilds:GetAPICapabilities(source) function(...) return APIContractBuilds:APICapabilitiesCallback(source, ...) end, {}) end +--- Updates the API capabilities for the source ---@param response table ---@param errMsg any ---@param source APISourceInfo @@ -119,6 +120,7 @@ function APIContractBuilds:APICapabilitiesCallback(source, response, errMsg) self.apiCapabilities[source.name] = parsedResponse end +--- Adds/Updates Builds for the source based on version 1 ---@param response table ---@param errMsg any ---@param source APICapabilities @@ -132,15 +134,15 @@ function APIContractBuilds:BuildsVersion1Callback(source, response, errMsg) end end ----Version 1 of the API Contract for Builds ----@param path string +--- Version 1 of the API Contract for Builds ---@param source APICapabilities -function APIContractBuilds:GetBuildsVersion1(path, source) - if source.endpointType ~= EndpointType.REST then +function APIContractBuilds:GetBuildsVersion1(source) + if source.endpointType == EndpointType.CSV then + -- TODO: Implement CSV Parsing and Format return end - launch:DownloadPage(source.baseAPIPath + path, function(...) + launch:DownloadPage(source.baseAPIPath + "/v1/builds", function(...) self:BuildsVersion1Callback(source, ...) end, {}) end From 5109fff879830f66aa7b2568ed0369a17d731b6e Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 11:46:37 +0200 Subject: [PATCH 05/10] feat: filter params to query support --- src/Classes/APIContractBuilds.lua | 61 ++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/src/Classes/APIContractBuilds.lua b/src/Classes/APIContractBuilds.lua index a3f45a2a88..286258ea26 100644 --- a/src/Classes/APIContractBuilds.lua +++ b/src/Classes/APIContractBuilds.lua @@ -49,10 +49,16 @@ local EndpointType = { ---@field name string ---@field fallbackVersion integer ---@field endpointType EndpointType +---@field supportedVersion? integer ---@field baseAPIPath? string ---@field league_filter? boolean ---@field gem_filter? boolean +--- Build version 1 Filter option +---@class BuildVersion1Filter +---@field league string +---@field gem string + --- This primarily exists for the lua language server ---@param buildInfo BuildInfo ---@param source APICapabilities @@ -67,6 +73,25 @@ local function buildInfoToCache(buildInfo, source) } end +---@param t table +local function tableToQueryParams(t) + if #t == 0 then + return "" + end + local query = "?" + for key, value in pairs(t) do + if value then + query = query .. key .. "=" .. value .. "&" + end + end + -- remove trailing & + if #t > 0 then + query = query:sub(1, #query - 1) + end + + return query +end + ---@class APIContractBuilds ---@field buildList table ---@field apiCapabilities table @@ -81,11 +106,36 @@ local APIContractBuilds = newClass("APIContractBuilds", local getBuildVersions = { [0] = function(...) return APIContractBuilds:GetBuildsVersion1(...) end, } +-- Switch case for GET Endpoint for Builds +local getBuildFilterVersions = { + [0] = function(data) return APIContractBuilds:GetBuildVersion1Filter(data) end, +} + +---@param data table +function APIContractBuilds:GetBuildVersion1Filter(data) + return { + league = data.league, + gem = data.gem + } +end --- Gets the builds from the source ----@param source APISourceInfo -function APIContractBuilds:GetBuilds(source) - getBuildVersions[source.fallbackVersion](source.endpointType) +---@param source APICapabilities +---@param data table +function APIContractBuilds:GetBuilds(source, data) + local getBuildsFunction = nil + local getBuildsFilterFunction = nil + if not source.supportedVersion then + getBuildsFunction = getBuildVersions[source.fallbackVersion] + getBuildsFilterFunction = getBuildFilterVersions[source.fallbackVersion] + else + getBuildsFunction = getBuildVersions[source.supportedVersion] + getBuildsFilterFunction = getBuildFilterVersions[source.supportedVersion] + end + + if getBuildsFunction and getBuildsFilterFunction then + getBuildsFunction(source.endpointType, getBuildsFilterFunction(data), source) + end end ---@param source APISourceInfo @@ -136,13 +186,14 @@ end --- Version 1 of the API Contract for Builds ---@param source APICapabilities -function APIContractBuilds:GetBuildsVersion1(source) +---@param params BuildVersion1Filter +function APIContractBuilds:GetBuildsVersion1(source, params) if source.endpointType == EndpointType.CSV then -- TODO: Implement CSV Parsing and Format return end - launch:DownloadPage(source.baseAPIPath + "/v1/builds", function(...) + launch:DownloadPage(source.baseAPIPath .. "/v1/builds" .. tableToQueryParams(params), function(...) self:BuildsVersion1Callback(source, ...) end, {}) end From 08432339102c1d4acf20c0c5bf6202a7df8c1f4c Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 11:46:49 +0200 Subject: [PATCH 06/10] fix: incorrect lua concatenation --- src/Classes/APIContractBuilds.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/APIContractBuilds.lua b/src/Classes/APIContractBuilds.lua index 286258ea26..36cf9de8f5 100644 --- a/src/Classes/APIContractBuilds.lua +++ b/src/Classes/APIContractBuilds.lua @@ -180,7 +180,7 @@ function APIContractBuilds:BuildsVersion1Callback(source, response, errMsg) for _, build in ipairs(parsedResponse) do -- source and buildId will be used as a caching key -- to avoid buildId collissions - self.buildList[common.sha1(source.name + "-" + build.buildId)] = buildInfoToCache(build, source) + self.buildList[common.sha1(source.name .. "-" .. build.buildId)] = buildInfoToCache(build, source) end end From 81841ccb8c736640a32ee7fa92f1a133a4dbebc7 Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 12:05:11 +0200 Subject: [PATCH 07/10] fix: incorrect index for api version --- src/Classes/APIContractBuilds.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Classes/APIContractBuilds.lua b/src/Classes/APIContractBuilds.lua index 36cf9de8f5..560530189c 100644 --- a/src/Classes/APIContractBuilds.lua +++ b/src/Classes/APIContractBuilds.lua @@ -104,11 +104,11 @@ local APIContractBuilds = newClass("APIContractBuilds", -- Switch case for GET Endpoint for Builds local getBuildVersions = { - [0] = function(...) return APIContractBuilds:GetBuildsVersion1(...) end, + [1] = function(...) return APIContractBuilds:GetBuildsVersion1(...) end, } -- Switch case for GET Endpoint for Builds local getBuildFilterVersions = { - [0] = function(data) return APIContractBuilds:GetBuildVersion1Filter(data) end, + [1] = function(data) return APIContractBuilds:GetBuildVersion1Filter(data) end, } ---@param data table From 30452de1849bf187502865e17dd698068055f820 Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 13:10:11 +0200 Subject: [PATCH 08/10] feat: support for multivalue k/v pairs --- docs/APIContract.md | 38 ++++++++++++++++++++----------- src/Classes/APIContractBuilds.lua | 4 ++++ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/docs/APIContract.md b/docs/APIContract.md index 0d558e8b44..d27708b33a 100644 --- a/docs/APIContract.md +++ b/docs/APIContract.md @@ -9,10 +9,22 @@ The base URL for an API should be: _baseURL_/_apiVersion_/ meaning even somethin In order to provide a consistent API a metadata endpoint should be provided under _baseURL_/.well-known/pathofbuilding this endpoint should provide information about the API and the version of the API. Furthermore this may allow having custom endpoints for the API. -| Feature | Field | Type | Description | -| ---------------- | ------------- | ---- | --------------------------------------------------------------------------------- | -| League Filtering | league_filter | bool | This can be used to indicate whether the API supports filtering based on leagues | -| Gem Filtering | gem_filter | bool | This can be used to indicate whether the API supports filtering based on gems | +| Feature | Field | Type | Description | +| ---------------- | ------------- | ------------ | --------------------------------------------------------------------------------- | +| League Filtering | league_filter | bool | This can be used to indicate whether the API supports filtering based on leagues | +| Gem Filtering | gem_filter | bool | This can be used to indicate whether the API supports filtering based on gems | +| Streams | streams | StreamInfo[] | A list of streams available to be queried against | + +### Types + +#### StreamInfo + +| Field | Type | Description | +| ------- | ------ | ------------------------------- | +| name | string | Name of the stream | +| apiPath | string | API path to the stream endpoint | + +apiPath might be changed to a generic endpoint such as `/v1/{stream}/builds` ## Version 1 @@ -30,7 +42,7 @@ Furthermore this may allow having custom endpoints for the API. ### Endpoints
- GET /v1/builds (Lists multiple builds) + GET /v1/{stream}/builds (Lists multiple builds) #### Parameters > Query Parameters @@ -43,19 +55,19 @@ Furthermore this may allow having custom endpoints for the API. ##### League -The values should be matching what Grinding Gear Games will be using for the teaser part of the website, such as: _https://www.pathofexile.com/settlers_ or _https://www.pathofexile.com/affliction_. This allows for easier mapping of the data as neither PoB nor the API will be required to wait for either party. +These values will just be the base patch version for the league. These links are generally available via poewiki see: https://www.poewiki.net/wiki/Necropolis_league _Official Page_. Example values: -| Patch | League | value | url | -| ----- | ---------------------- | ---------- | -------------------------------------- | -| 3.25 | Settlers of Kalguur | settlers | https://www.pathofexile.com/settlers | -| 3.24 | Necropolis | necropolis | https://www.pathofexile.com/necropolis | -| 3.23 | Affliction | affliction | https://www.pathofexile.com/affliction | -| 3.22 | Trial of the Ancestors | ancestor | https://www.pathofexile.com/ancestor | -| 3.4 | Delve | delve | https://www.pathofexile.com/delve | +| Patch | League | value | url | +| ----- | ---------------------- | ----- | -------------------------------------- | +| 3.25 | Settlers of Kalguur | 3.25 | https://www.pathofexile.com/settlers | +| 3.24 | Necropolis | 3.24 | https://www.pathofexile.com/necropolis | +| 3.23 | Affliction | 3.23 | https://www.pathofexile.com/affliction | +| 3.22 | Trial of the Ancestors | 3.22 | https://www.pathofexile.com/ancestor | +| 3.4 | Delve | 3.4 | https://www.pathofexile.com/delve | #### Responses diff --git a/src/Classes/APIContractBuilds.lua b/src/Classes/APIContractBuilds.lua index 560530189c..2d734bec38 100644 --- a/src/Classes/APIContractBuilds.lua +++ b/src/Classes/APIContractBuilds.lua @@ -81,6 +81,10 @@ local function tableToQueryParams(t) local query = "?" for key, value in pairs(t) do if value then + local tempValue = value + if type(value) == "table" then + tempValue = table.concat(value, ",") + end query = query .. key .. "=" .. value .. "&" end end From a9323f329fb32aeb987ce1e794cf4b5fdecfeb3b Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 16:50:53 +0200 Subject: [PATCH 09/10] docs: proposal build update support --- docs/APIContract.md | 61 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/docs/APIContract.md b/docs/APIContract.md index d27708b33a..412b94b549 100644 --- a/docs/APIContract.md +++ b/docs/APIContract.md @@ -9,11 +9,12 @@ The base URL for an API should be: _baseURL_/_apiVersion_/ meaning even somethin In order to provide a consistent API a metadata endpoint should be provided under _baseURL_/.well-known/pathofbuilding this endpoint should provide information about the API and the version of the API. Furthermore this may allow having custom endpoints for the API. -| Feature | Field | Type | Description | -| ---------------- | ------------- | ------------ | --------------------------------------------------------------------------------- | -| League Filtering | league_filter | bool | This can be used to indicate whether the API supports filtering based on leagues | -| Gem Filtering | gem_filter | bool | This can be used to indicate whether the API supports filtering based on gems | -| Streams | streams | StreamInfo[] | A list of streams available to be queried against | +| Feature | Field | Type | Description | +| ---------------- | ------------- | ---------------- | ------------------------------------------------------------------------------------ | +| League Filtering | league_filter | bool | This can be used to indicate whether the API supports filtering based on leagues | +| Gem Filtering | gem_filter | bool | This can be used to indicate whether the API supports filtering based on gems | +| Streams | streams | StreamInfo[] | A list of streams available to be queried against | +| Update Builds | update_builds | UpdateBuildsInfo | Indicates if the API supports updating builds via PoB and which fields are supported | ### Types @@ -26,6 +27,21 @@ Furthermore this may allow having custom endpoints for the API. apiPath might be changed to a generic endpoint such as `/v1/{stream}/builds` +#### UpdateBuildsInfo + +| Field | Type | Description | +| ---------- | -------- | ------------------------------------------------------ | +| hasSupport | bool | indicates if the API supports updating external builds | +| fields | string[] | list of fields that can be updated | + +Example: + +```json +{ + "hasSupport": true, + "fields": ["description", "youtubeUrl"] +} +``` ## Version 1 ### Response and Request types @@ -42,7 +58,7 @@ apiPath might be changed to a generic endpoint such as `/v1/{stream}/builds` ### Endpoints
- GET /v1/{stream}/builds (Lists multiple builds) + GET /v1/builds (Lists multiple builds) #### Parameters > Query Parameters @@ -77,3 +93,36 @@ Example values:
+ +
+ POST /v1/builds/{buildId} (Update a single build on the source) + +#### Parameters +> Path Parameters + +| name | type | data type | description | +| ------- | -------- | --------- | ---------------------------------------------------------- | +| buildId | required | string | The build in question on the source that should be updated | + +#### Request + +| Field | Type | Description | +| ---------- | -------- | ---------------------------------- | +| pobdata | string | The Path of Building data | +| name | string | The name of the build | +| customData | string[] | A list of custom data to be stored | + +customData will be describable fields via the metadata endpoint, if customData is empty it is expected to be ignored and no changes should be made. + +#### Responses + +| http code | content-type | response | Description | +| --------- | -------------------------- | --------------------- | ---------------------- | +| `200` | `application/json` | None | Update succesful | +| `201` | `application/json` | None | Succesful creation | +| `400` | `text/html; charset=utf-8` | `Reason for failure` | Input may be incorrect | +| `401` | `text/html; charset=utf-8` | `Reason if necessary` | Auth incorrect | +| `404` | `text/html; charset=utf-8` | None | Build does not exist | + +
+ From bc5536a8c6061667b9cf39a7fff93f812523599f Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Fri, 26 Jul 2024 16:58:26 +0200 Subject: [PATCH 10/10] chore: cleanup & organize --- docs/APIContract.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/APIContract.md b/docs/APIContract.md index 412b94b549..84278f69b9 100644 --- a/docs/APIContract.md +++ b/docs/APIContract.md @@ -9,6 +9,7 @@ The base URL for an API should be: _baseURL_/_apiVersion_/ meaning even somethin In order to provide a consistent API a metadata endpoint should be provided under _baseURL_/.well-known/pathofbuilding this endpoint should provide information about the API and the version of the API. Furthermore this may allow having custom endpoints for the API. +
Specification | Feature | Field | Type | Description | | ---------------- | ------------- | ---------------- | ------------------------------------------------------------------------------------ | | League Filtering | league_filter | bool | This can be used to indicate whether the API supports filtering based on leagues | @@ -16,9 +17,11 @@ Furthermore this may allow having custom endpoints for the API. | Streams | streams | StreamInfo[] | A list of streams available to be queried against | | Update Builds | update_builds | UpdateBuildsInfo | Indicates if the API supports updating builds via PoB and which fields are supported | +
+ ### Types -#### StreamInfo +
StreamInfo | Field | Type | Description | | ------- | ------ | ------------------------------- | @@ -26,9 +29,9 @@ Furthermore this may allow having custom endpoints for the API. | apiPath | string | API path to the stream endpoint | apiPath might be changed to a generic endpoint such as `/v1/{stream}/builds` +
-#### UpdateBuildsInfo - +
UpdateBuildsInfo | Field | Type | Description | | ---------- | -------- | ------------------------------------------------------ | | hasSupport | bool | indicates if the API supports updating external builds | @@ -42,11 +45,13 @@ Example: "fields": ["description", "youtubeUrl"] } ``` +
+ ## Version 1 ### Response and Request types -#### BuildInfo +
BuildInfo | Field | Type | Description | | ------------ | ------- | ----------------------------------- | @@ -54,6 +59,7 @@ Example: | name | string | The name of the build | | lastModified | integer | The last modification timestamp | | buildId | string | The unique identifier for the build | +
### Endpoints