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

feat: add API documentation following OpenAPI standard #13

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

kenyiu
Copy link
Contributor

@kenyiu kenyiu commented Mar 1, 2025

Description

This PR adds API documentation to the project following the OpenAPI standard. The documentation provides a comprehensive overview of the API endpoints, request/response formats, and other relevant details.

Changes

  • Added OpenAPI specification file (src/drand-api.yaml)
  • Added package docusaurus-plugin-openapi-docs and docusaurus-theme-openapi-docs for the generation of mdx from yaml
  • Updated relevant documentation files

Reason

Adding API documentation following the OpenAPI standard ensures that our API is well-documented and easily understandable by developers. It also facilitates better integration and usage of the API by providing a clear and standardized format.

- Upgraded @docusaurus/core to the 3.7
- Upgraded @docusaurus/preset-classic to the 3.7
- Upgraded @docusaurus/module-type-aliases to 3.7
- Upgraded @docusaurus/tsconfig to 3.7
- Upgraded @docusaurus/types to 3.7
- Added missing API endpoints to the OpenAPI specification
- Updated summaries to reflect the paths in the OpenAPI documentation
- Ensured all API endpoints are documented in the drand-api.yaml file
- Updated Docusaurus configuration to include the OpenAPI documentation
@kenyiu kenyiu marked this pull request as ready for review March 9, 2025 13:17
sidebar_label: "/:chain-hash/info"
hide_title: true
hide_table_of_contents: true
api: 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
Copy link
Contributor

Choose a reason for hiding this comment

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

what is this large base64 blob?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are metadata for the API generated by the docusaurus-plugin-openapi-docs package from the yaml files. (yarn docusaurus clean-api-docs all && yarn docusaurus gen-api-docs all)

The string will be used here afterwards:
https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/blob/e4d3ec4ebfb8415e97951076ce2f0901e8d88168/packages/docusaurus-theme-openapi-docs/src/theme/ApiItem/index.tsx#L78

I have wrote a quick script for you to check what's stored in the blob.

const pako = require('pako');

function base64ToUint8Array(base64) {
  const binary = atob(base64);
  const len = binary.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return bytes;
}
let api = "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";
apiJson = JSON.parse(
  new TextDecoder().decode(pako.ungzip(base64ToUint8Array(api)))
);
console.log(apiJson);

The output would be:

{
  description: 'Retrieves metadata about a specific randomness chain, identified by its chain hash.',
  parameters: [
    {
      name: 'chain-hash',
      in: 'path',
      required: true,
      schema: [Object],
      example: '8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce',
      description: 'The hexadecimal hash identifying the chain (e.g., default chained network).'
    }
  ],
  responses: {
    '200': { description: 'Chain information\n', content: [Object] },
    '404': { description: 'Chain not found', content: [Object] }
  },
  method: 'get',
  path: '/{chain-hash}/info',
  servers: [
    {
      url: 'https://drand.cloudflare.com',
      description: 'Cloudflare - Public endpoint for the League of Entropy mainnet'
    },
    {
      url: 'https://api.drand.secureweb3.com:6875',
      description: 'Storswift - Public endpoint for the League of Entropy mainnet'
    },
    {
      url: 'https://pl-us.testnet.drand.sh',
      description: 'Protocol Labs - US-based testnet endpoint'
    },
    {
      url: 'https://pl-eu.testnet.drand.sh',
      description: 'Protocol Labs - EU-based testnet endpoint'
    },
    {
      url: 'https://testnet-api.drand.cloudflare.com',
      description: 'Cloudflare - Testnet endpoint'
    }
  ],
  info: {
    title: 'drand HTTP API',
    description: 'Drand provides a JSON HTTP interface that clients can use to fetch randomness from each drand network running on nodes.\n' +
      "If you're using drand in an application, it may be easier and more secure to use one of the client libraries, \n" +
      'which will also perform verification of randomness rounds and add additional features like failover, racing, aggregation, \n' +
      'and caching.\n' +
      '\n' +
      "All that's required is the address of the HTTP interface and way to fetch from HTTP, e.g. curl.\n" +
      '\n' +
      'The version 1 of public [League of Entropy](https://blog.cloudflare.com/league-of-entropy/) HTTP APIs are available at:\n' +
      '- Cloudflare\n' +
      '  - https://drand.cloudflare.com\n' +
      '- Storswift\n' +
      '  - https://api.drand.secureweb3.com:6875\n' +
      '\n' +
      'The League of Entropy currently runs two networks in mainnet: default and fastnet. \n' +
      'They are chained and unchained networks respectively, the details of which can be found in the [cryptography \n' +
      'specification](https://drand.love/docs/cryptography/#randomness).\n' +
      '\n' +
      'The chain hash for the League of Entropy default chain running at a 30s frequency in chained mode on Mainnet is:\n' +
      '`8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce`\n' +
      '\n' +
      'It also available at the default context, i.e. omitting the `/{chain-hash}` in the API specification below.\n' +
      '\n' +
      'The chain hash for the League of Entropy quicknet network running at a 3s frequency in unchained mode on Mainnet is:\n' +
      '`52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971`\n' +
      '\n' +
      'Note that [the fastnet network has been deprecated..](https://drand.love/blog/2023/07/03/fastnet-sunset-quicknet-new/)\n' +
      '\n' +
      'Furthermore, we have "testnet endpoints" which are a completely separate environment for testing our latest changes, \n' +
      'potentially helping you detect breaking changes or issues with our latest release before they hit mainnet. \n' +
      'We recommend running your CI/CD against our testnet endpoints as well as our mainnet ones, in order to detect issues early.\n' +
      '\n' +
      'We currently have 3 testnet HTTP(S) endpoints being run by:\n' +
      '\n' +
      '- Protocol Labs\n' +
      '  - https://pl-us.testnet.drand.sh\n' +
      '  - https://pl-eu.testnet.drand.sh\n' +
      '- Cloudflare\n' +
      '  - https://testnet-api.drand.cloudflare.com\n' +
      '\n' +
      'As you can see, they are currently running various chains as explained below. \n' +
      'We are committed to maintaining the default, G2 based, chained testnet chain \n' +
      '(`84b2234fb34e835dccd048255d7ad3194b81af7d978c3bf157e3469592ae4e02`) as well as \n' +
      'the faster, G1 based, unchained quicknet-t testnet chain \n' +
      '(`cc9c398442737cbd141526600919edd69f1d6f9b4adb67e4d912fbc64341a9a5`) \n' +
      'as long as we run the equivalent mainnet networks.\n' +
      '\n' +
      'Other testnet chains, such as our first "unchained" testnet \n' +
      '(`7672797f548f3f4748ac4bf3352fc6c6b6468c9ad40ad456a397545c6e2df5bf`) or our first G1 based non-RFC compliant chain\n' +
      '(f3827d772c155f95a9fda8901ddd59591a082df5ac6efe3a479ddb1f5eeb202c) may be deprecated in the future. \n',
    version: '1.0.0',
    contact: { name: 'drand Team', url: 'https://drand.love/' },
    license: {
      name: 'Apache 2.0 or MIT',
      url: 'https://github.com/drand/drand/blob/main/LICENSE'
    }
  },
  postman: {
    name: '/:chain-hash/info',
    description: {
      content: 'Retrieves metadata about a specific randomness chain, identified by its chain hash.',
      type: 'text/plain'
    },
    url: { path: [Array], host: [Array], query: [], variable: [Array] },
    header: [ [Object] ],
    method: 'GET'
  }
}

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

Successfully merging this pull request may close these issues.

2 participants