Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Refactored openapi sepcifications and build doc #2124

Closed
wants to merge 1 commit into from

Conversation

NagyZoltanPeter
Copy link
Contributor

Description

This PR is an effort towards a slim and comprehensive Rest API specification and documentation.
Please take it as a reasoning on choices we can have as well as a source of proposal. (In this manner please feel free to invite others to give opinions)

Current Waku node interface specifications are living next to each endpoint implementation and not really used to provide a real help for waku users on how they can access their node running.

To reach this I think best move is to merge these separate specifications and use as single source of truth.
Although from maintenance point of view i think it is better to have it well splitted up yet being able to organized in hierarchy.
I found unfortunate the OpenApi specification rules are a bit too restrictive on this but was able to reorganize under one openapi.yaml - as a root of the specification - while having endpoints defined alone.
Schema specification was also aimed to get common and eliminate duplications.

This approach is presented here.

There are few things to get decided.

  • Is this the right place where Rest-api interface specification should live?
    • My proposal is the keep it in the nwaku repository as nwaku is the reference implementation of wakunode. Having it in a separate repository bears the risk to get forgotten updated.
    • Having them duplicated in go-waku also has the risks of branching from each other.
  • Is this the right form of having a maintainable api specification?
  • What form we should use it as documentation for waku users?
    • My proposal is to use it as a single source of truth and generate our doc page out of it right from nwaku master branch.
    • Where to fit this generated doc page?

For getting an impression I created a generated api doc under my gh pages:
https://nagyzoltanpeter.github.io/nwaku-api/index.html

  • This one now is in my repository and fed from my dev branch's head.
    • This is intended to move where we decide to place such doc and shall be fed from master's head (or?)
  • The renderer engine is from RapiDoc and used in a local copy in my repository. This has MIT license.
  • Of course there is a lot of chance to make it nicer and customized as needed.

Changes

  • All openapi.yaml files are moved under waku/waku_api/rest/doc
  • There is one openapi.yaml as a root.
  • Each endpoint yaml's are named accordingly and following the rules of Openapi spec referencing conventions
  • schema types is in one common file under .../rest/doc/schemas
  • No code changes done now
    • There are some renaming in the spec (in store endpoint - agreed with @Ivansete-status - to get common naming)
    • This one should be follow up in later PR in the code as well.

Issue

#2120

…/doc

Separated paths and types while having one common doc for the whole api
Upon this base we are able to generate api documentation on the fly to the web.
@NagyZoltanPeter NagyZoltanPeter added the E:REST API service node See https://github.com/waku-org/pm/issues/82 for details label Oct 13, 2023
@NagyZoltanPeter NagyZoltanPeter self-assigned this Oct 13, 2023
@NagyZoltanPeter NagyZoltanPeter linked an issue Oct 13, 2023 that may be closed by this pull request
@github-actions
Copy link

You can find the image built from this PR at

quay.io/wakuorg/nwaku-pr:2124

Built from 0e1be7c

@fbarbu15
Copy link
Contributor

Good job! This facilitates the creation of automated tests based on specs, utilizing OpenAPI tools. From schema validators to automated test generation

@chair28980 chair28980 removed the E:REST API service node See https://github.com/waku-org/pm/issues/82 for details label Oct 17, 2023
@chaitanyaprem
Copy link
Contributor

chaitanyaprem commented Oct 19, 2023

Is this the right place where Rest-api interface specification should live?
My proposal is the keep it in the nwaku repository as nwaku is the reference implementation of wakunode. Having it in a separate repository bears the risk to get forgotten updated.
Having them duplicated in go-waku also has the risks of branching from each other.

I think we should place this spec in a separate repo under wak-org similar to how we are storing proto files at https://github.com/waku-org/waku-proto or place it under rfc repo(with the REST API rfc).
This way, spec is maintained independent of implementations and each implementation can refer to a version of the spec which can be specified in the implementations documentation.
The process to update REST API's should be first to update the spec, get it reviewed and then implement the spec. This is a process which i have seen followed across many orgs and works well.

@@ -0,0 +1,37 @@
get:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the API documentation rather the API specification.
It would make sense to call this folder spec(wherever we decide to keep it), because doc is what can be generated from this API spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I accept it!

schema:
type: array
items:
type: string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having string here is ambigous, better to have a comment or a type indicating what info is required to be passed.
A user of the API will not know what to be passed, is it just a peerID? If so, how about multiAddress ?

content:
application/json:
schema:
$ref: './schemas/apitypes.yaml#/WakuInfo'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit: but maybe we can rename WakuInfo to LocalNodeInfo/WakuNodeInfo

application/json:
schema:
$ref: './schemas/apitypes.yaml#/WakuInfo'
'4XX':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you see a scenario where 4xx would be returned?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe, nice catch!

text/plain:
schema:
type: string
'4XX':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above, I don't see when 4xx would be returned for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, not!

only WakuMessages that are linked to any of the given
content topics will be delivered in the get response.
It should be a URL-encoded-comma-separated string.
example: 'my%20first%20content%20topic%2Cmy%20second%20content%20topic%2Cmy%20third%20content%20topic'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, not sure why the example has spaces.
Content-topics as i understand don't have spaces in them rather of the format "toychat/1/abc/proto". Example should reflect the same.

it can be part of the next page request.
example: '1680590947000000000'

- name: storeTime
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this and senderTime should be used.
Because each store node in the network may store the message at a different time, whereas senderTime would be same.
But maybe this is also more of a store protocol change.

it can be part of the next page request.
example: '1680590945000000000'

- name: digest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would happen if i specify multiple cursor fields?
better to document that behaviour so that users of the API are clear as well.

it can be part of the next page request.
example: 'Gc4ACThW5t2QQO82huq3WnDv%2FapPPJpD%2FwJfxDxAnR0%3D'

- name: pageSize
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If messageSize is too big to fit page size messages in a response, does the server truncate and chunk or send less than requested pageSize?

example: 'Gc4ACThW5t2QQO82huq3WnDv%2FapPPJpD%2FwJfxDxAnR0%3D'

- name: pageSize
in: query
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also curious to know how paging works, does the user need to keep querying until empty response is returned?

type: object
required:
- protocol
- connected
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connected need not be per protocol, this is per peer.
I am assuming this indicates whether node is connected with this peer or not and not per protocol.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our idea was to group protocol and info under peers. Of course having a peer with no protocol does not make sense, hence the required.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree that protocol is required, but what i meant is connected status need not be at same level with protocol.

What i am suggesting is that response should be in the following format. If you noticed the peer connection status is shown outside protocols. Also, one more query on this point, does this endpoint list all peers in the peerStore or only peers that we are currently connected to?

{
    "multiaddr":[
        "/ip4/10.0.0.133/tcp/60000/p2p/16Uiu2HAkymj3jUpK1eGaymZbGftwffVYtoMRgnd8sngC8sSJzabo", 
        "/ip4/127.0.0.1/tcp/60000/p2p/16Uiu2HAkymj3jUpK1eGaymZbGftwffVYtoMRgnd8sngC8sSJzabo"
    ],
    "connected": true,
    "protocols":[
        "/vac/waku/filter-push/2.0.0-beta1",
        "/vac/waku/relay/2.0.0"
    ]
}


Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding we list all peers we know and their supported protocols we maybe connected at query time.
Suppose that we can have several peers that supports filtering but currently we are using only one of them. (or same with store protocol).
@Ivansete-status WDYT?

@@ -0,0 +1,25 @@
# /relay/v1/auto/messages/{contentTopic}: # Note the plural in messages
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another reason for not having contentTopic as a URL param is since contentTopic format recommends having /, a user will have to URLencode the contentTopic before invoking the API. It is non-standard but if we include contentTopic in requestBody then this issue can be avoided.

While testing with postman for example with contentTopic /toychat/1/huilong/proto, i had to pass %2Ftoychat%2F1%2Fhuilong%2Fproto in order for this to work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had exactly this conversation in nwaku.
So far our conclusion was, that even though it requires url encoding, having GET request in content body is against rest convention and Http recommendation. But I could live with it having to do so.
Major issue was that the nim-presto implementation we use is - in align with the http spec - forbids having content body for a GET request.
So in order to do so we need to modify our HttpServer implementation.

I'm not sure how it is in your go impl. Does that allows it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In golang, the way we are implementing REST methods i don't see any limitation with this.
Will test once to confirm though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is even more extensive in store api. But as I see its only a problem if one would issue such and api call by hand, in all other programmatic case url encoding shall not be an issue.

- protocols
properties:
multiaddr:
type: string
Copy link
Contributor

@chaitanyaprem chaitanyaprem Oct 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this multiaddr should be an array of multiaddresses for the peer...as a peer can have more than 1 multiaddress advertising.

We should also include peeerID

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


It is allowed to refresh or add new content topic to an existing subscription.

Fields pubsubTopic and contentFilters must be filled.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With autosharding, pubsubTopic is not mandatory.
Only contentTopics can be filled and using autosharding algorithm, pubsubTopic is derived.
cc @chaitanyaprem , we need to change documentation for all APIs accordingly.

@fryorcraken fryorcraken removed their request for review October 27, 2023 03:51
@NagyZoltanPeter
Copy link
Contributor Author

@chaitanyaprem @harsh-98, @fryorcraken , @chair28980
I'm closig this PR as it this will live in a separate repository. However I will make a follow up issue to track these comments.
Some of them effect only api specification in semantic way but many other has consequences on nwaku and go-waku api implementations. Those must be tracked in separate issues.

New repository: https://github.com/waku-org/waku-rest-api
Generated api reference is living in the same repository's GH pages: https://waku-org.github.io/waku-rest-api/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

chore: Reorganize RestApi specs for live documentation
5 participants