From 95b3da41265645e8a4a038e3ebebbc56c30606cb Mon Sep 17 00:00:00 2001 From: Lorenzo Delgado Date: Wed, 15 Jun 2022 15:02:02 +0200 Subject: [PATCH] feat(rest): Add HTTP REST API (#727). Amend Debug REST API client --- tests/v2/test_rest_debug_api.nim | 11 +++- tests/v2/test_rest_debug_api_serdes.nim | 5 +- tests/v2/test_rest_serdes.nim | 5 +- .../{debug_api.nim => debug/api_types.nim} | 60 ++++--------------- waku/v2/node/rest/debug/debug_api.nim | 45 ++++++++++++++ waku/v2/node/rest/{ => debug}/debug_api.yaml | 14 ++++- 6 files changed, 85 insertions(+), 55 deletions(-) rename waku/v2/node/rest/{debug_api.nim => debug/api_types.nim} (51%) create mode 100644 waku/v2/node/rest/debug/debug_api.nim rename waku/v2/node/rest/{ => debug}/debug_api.yaml (74%) diff --git a/tests/v2/test_rest_debug_api.nim b/tests/v2/test_rest_debug_api.nim index c1a0cf629..3e3586ddf 100644 --- a/tests/v2/test_rest_debug_api.nim +++ b/tests/v2/test_rest_debug_api.nim @@ -1,12 +1,15 @@ +{.used.} + import stew/shims/net, chronicles, testutils/unittests, - presto, + presto, libp2p/crypto/crypto import ../../waku/v2/node/wakunode2, - ../../waku/v2/node/rest/[server, client, debug_api] + ../../waku/v2/node/rest/[server, client, utils], + ../../waku/v2/node/rest/debug/debug_api proc testWakuNode(): WakuNode = @@ -45,7 +48,9 @@ suite "REST API - Debug": # Then check: - response.listenAddresses == @[$node.switch.peerInfo.addrs[^1] & "/p2p/" & $node.switch.peerInfo.peerId] + response.status == 200 + response.contentType == $MIMETYPE_JSON + response.data.listenAddresses == @[$node.switch.peerInfo.addrs[^1] & "/p2p/" & $node.switch.peerInfo.peerId] await restServer.stop() await restServer.closeWait() diff --git a/tests/v2/test_rest_debug_api_serdes.nim b/tests/v2/test_rest_debug_api_serdes.nim index 35397b6cf..44ba77e8b 100644 --- a/tests/v2/test_rest_debug_api_serdes.nim +++ b/tests/v2/test_rest_debug_api_serdes.nim @@ -1,10 +1,13 @@ +{.used.} + import std/typetraits import chronicles, unittest2, stew/[results, byteutils], json_serialization import - ../../waku/v2/node/rest/[serdes, debug_api] + ../../waku/v2/node/rest/serdes, + ../../waku/v2/node/rest/debug/api_types suite "Debug API - serialization": diff --git a/tests/v2/test_rest_serdes.nim b/tests/v2/test_rest_serdes.nim index 3dfc16024..40c56dff0 100644 --- a/tests/v2/test_rest_serdes.nim +++ b/tests/v2/test_rest_serdes.nim @@ -1,10 +1,13 @@ +{.used.} + import std/typetraits import chronicles, unittest2, stew/[results, byteutils], json_serialization import - ../../waku/v2/node/rest/[serdes, debug_api] + ../../waku/v2/node/rest/serdes, + ../../waku/v2/node/rest/debug/api_types # TODO: Decouple this test suite from the `debug_api` module by defining diff --git a/waku/v2/node/rest/debug_api.nim b/waku/v2/node/rest/debug/api_types.nim similarity index 51% rename from waku/v2/node/rest/debug_api.nim rename to waku/v2/node/rest/debug/api_types.nim index 41a113aa9..4dfad279b 100644 --- a/waku/v2/node/rest/debug_api.nim +++ b/waku/v2/node/rest/debug/api_types.nim @@ -1,16 +1,11 @@ {.push raises: [Defect].} import - stew/byteutils, chronicles, json_serialization, - json_serialization/std/options, - presto/[route, client] -import "."/[serdes, utils], - ../wakunode2 - -logScope: topics = "rest_api_debug" - + json_serialization/std/options +import ".."/serdes +import ../../wakunode2 #### Types @@ -20,6 +15,15 @@ type enrUri*: Option[string] +#### Type conversion + +proc toDebugWakuInfo*(nodeInfo: WakuInfo): DebugWakuInfo = + DebugWakuInfo( + listenAddresses: nodeInfo.listenAddresses, + enrUri: some(nodeInfo.enrUri) + ) + + #### Serialization and deserialization proc writeValue*(writer: var JsonWriter[RestJson], value: DebugWakuInfo) @@ -55,42 +59,4 @@ proc readValue*(reader: var JsonReader[RestJson], value: var DebugWakuInfo) value = DebugWakuInfo( listenAddresses: listenAddresses.get, enrUri: enrUri - ) - - -#### Server request handlers - -proc toDebugWakuInfo(nodeInfo: WakuInfo): DebugWakuInfo = - DebugWakuInfo( - listenAddresses: nodeInfo.listenAddresses, - enrUri: some(nodeInfo.enrUri) - ) - -const ROUTE_DEBUG_INFOV1* = "/debug/v1/info" - -proc installDebugInfoV1Handler(router: var RestRouter, node: WakuNode) = - router.api(MethodGet, ROUTE_DEBUG_INFOV1) do () -> RestApiResponse: - let info = node.info().toDebugWakuInfo() - let resp = RestApiResponse.jsonResponse(info, status=Http200) - if resp.isErr(): - debug "An error ocurred while building the json respose", error=resp.error() - return RestApiResponse.internalServerError() - - return resp.get() - -proc installDebugApiHandlers*(router: var RestRouter, node: WakuNode) = - installDebugInfoV1Handler(router, node) - - -#### Client - -proc decodeBytes*(t: typedesc[DebugWakuInfo], data: openArray[byte], contentType: string): RestResult[DebugWakuInfo] = - if MediaType.init(contentType) != MIMETYPE_JSON: - error "Unsupported respose contentType value", contentType = contentType - return err("Unsupported response contentType") - - let decoded = ?decodeFromJsonBytes(DebugWakuInfo, data) - return ok(decoded) - -# TODO: Check how we can use a constant to set the method endpoint (improve "rest" pragma under nim-presto) -proc debugInfoV1*(): DebugWakuInfo {.rest, endpoint: "/debug/v1/info", meth: HttpMethod.MethodGet.} \ No newline at end of file + ) \ No newline at end of file diff --git a/waku/v2/node/rest/debug/debug_api.nim b/waku/v2/node/rest/debug/debug_api.nim new file mode 100644 index 000000000..379b93df5 --- /dev/null +++ b/waku/v2/node/rest/debug/debug_api.nim @@ -0,0 +1,45 @@ +{.push raises: [Defect].} + +import + stew/byteutils, + chronicles, + json_serialization, + json_serialization/std/options, + presto/[route, client] +import "."/api_types +import ".."/[serdes, utils] +import ../../wakunode2 + +logScope: topics = "rest_api_debug" + + +#### Server request handlers + +const ROUTE_DEBUG_INFOV1* = "/debug/v1/info" + +proc installDebugInfoV1Handler(router: var RestRouter, node: WakuNode) = + router.api(MethodGet, ROUTE_DEBUG_INFOV1) do () -> RestApiResponse: + let info = node.info().toDebugWakuInfo() + let resp = RestApiResponse.jsonResponse(info, status=Http200) + if resp.isErr(): + debug "An error occurred while building the json respose", error=resp.error() + return RestApiResponse.internalServerError() + + return resp.get() + +proc installDebugApiHandlers*(router: var RestRouter, node: WakuNode) = + installDebugInfoV1Handler(router, node) + + +#### Client + +proc decodeBytes*(t: typedesc[DebugWakuInfo], data: openArray[byte], contentType: string): RestResult[DebugWakuInfo] = + if MediaType.init(contentType) != MIMETYPE_JSON: + error "Unsupported respose contentType value", contentType = contentType + return err("Unsupported response contentType") + + let decoded = ?decodeFromJsonBytes(DebugWakuInfo, data) + return ok(decoded) + +# TODO: Check how we can use a constant to set the method endpoint (improve "rest" pragma under nim-presto) +proc debugInfoV1*(): RestResponse[DebugWakuInfo] {.rest, endpoint: "/debug/v1/info", meth: HttpMethod.MethodGet.} diff --git a/waku/v2/node/rest/debug_api.yaml b/waku/v2/node/rest/debug/debug_api.yaml similarity index 74% rename from waku/v2/node/rest/debug_api.yaml rename to waku/v2/node/rest/debug/debug_api.yaml index cc1fdf1f3..1a17ee902 100644 --- a/waku/v2/node/rest/debug_api.yaml +++ b/waku/v2/node/rest/debug/debug_api.yaml @@ -1,15 +1,23 @@ -openapi: 3.1.0 +openapi: 3.0.3 info: - title: Waku REST API - Debug + title: Waku V2 node REST API version: 1.0.0 + contact: + name: VAC Team + url: https://forum.vac.dev/ + +tags: + - name: debug + description: Debug REST API for WakuV2 node paths: /debug/v1/info: get: summary: Get node info description: Retrieve information about a Waku v2 node. + operationId: getNodeInfo tags: - - Debug + - debug responses: '200': description: Information about a Waku v2 node.