GithubHelp home page GithubHelp logo

grpc-docs's Introduction

gRPC Docs logo

Interactive gRPC API Documentation

NPM JavaScript Style Guide

We're like Swagger UI, but for gRPC APIs. Give us a star if you like the project.

Live demo

Live demo is available at https://gendocu-demo.web.app/.

gRPC Docs logo

Quickstart

docker run -rm --network host \
  -v <your-proto-root>:/input \
  -v $(pwd)/output:/output \
  gendocu/grpc-docs

Install

Only for node 12+ (you can check your node version with node -v)

npm install --save grpc-docs

Or

yarn add grpc-docs

Usage

You can find all the integration types in example/src/App.tsx file.

You can use this widget standalone or with GenDocu Cloud gRPC CI/CD. Feature comparison is below.

Running example

  1. Clone this project
  2. Go to example directory and use yarn start to run the frontend
  3. In case you want be able to modify the library open the repository root directory in second terminal and run yarn start

Standalone within existing react frontend

  1. Install grpc-docs - instruction in Setup section
  2. Generate json description from protobuf api with project protoc-gen-doc: protoc --doc_out=./ --doc_opt=json,description.json *.proto
  3. Inside your React project create API Reference component - you can see example of usage in example/src/App.tsx
import React from 'react'

import { GRPCSelfGeneratedAPIReference } from 'grpc-docs'

const Example = () => {
  // return <GRPCSelfGeneratedAPIReference file='url-to-json-description-of-api'/>

  // return <GRPCSelfGeneratedAPIReference definition='A json string definition that got generated by protoc'/>

  return <GRPCSelfGeneratedAPIReference file='example-descriptors/description.json'/>
}
  1. [optional] You can also provide the environments and authentication description - add scheme='path-to-scheme-file.yaml'. Use GenDocu Cloud Api Specification Scheme. You can find example file here.

Hosting the generated protoc JSON behind auth.

You can provide a protoc definition as text directly to the <GRPCSelfGeneratedAPIReference /> component. So you should be able to fetch your hosted json with the correct headers and provide it to the compoenent in the definition prop.

import React from 'react'

import { GRPCSelfGeneratedAPIReference } from 'grpc-docs'

const Example = async () => {
  const resp = await fetch('my-company.com/protoc.json')
  const definition = await resp.text()

  return <GRPCSelfGeneratedAPIReference definition={definition}/>
}

With GenDocu

  1. Install grpc-docs - instruction in Setup section
  2. Create a project on Gendocu Cloud
  3. Use component inside your React project
import React from 'react'

import { GRPCGenDocuAPIReference } from 'grpc-docs'

const App = () => {
  //return <GRPCGenDocuAPIReference project='your-gendocu-project' organization='your-organization'/>
  return <GRPCGenDocuAPIReference project='LibraryApp' organization='gendocu'/>
}
export default App;

You can also implement your own backend wrapper - API documentation is available here.

Feature comparison

Feature Standalone gRPC-docs gRPC-docs with GenDocu GenDocu Developer Portal
Setup steps
API Reference
Code snippets
Password protected documentation
Programming languages 1 6 6
Environment selection ❌^ ❌^
Authentication description ❌^ ❌^
Try it out ❌^
RBAC protected documentation
SSO

^ to be implemented

Customize style

To create your own styled documentation change the implementation in style/default - you can find there all the files implementing the UI of documentation. We strongly recommend to create own style directory, like style/my-style instead of overwriting the style/default components.

Troubleshooting

  1. ... is not allowed. Add this origin in your documentation settings. You have to add the host in your GenDocu project settings. If the project is not owned by you, ask project owner.

License

MIT © gendocu-com

grpc-docs's People

Contributors

bartek1912 avatar kissmikijr avatar gianlucaparadise avatar

Stargazers

 avatar Aung Pyae Phyo avatar Thet Khine avatar Brandon Luth avatar Erik Hansen avatar Nickolay Medvedev avatar J.R. Morgan avatar  avatar  avatar Daniel de Jong avatar Marcello DeSales avatar Kanata Miyahana avatar Anton Kornilov avatar  avatar  avatar ONDA, Takashi avatar James avatar Ankur Kumar avatar Ivan Klimchuk avatar L.B. avatar Jeffrey Doto avatar Sam Griffith avatar Adam Yarger avatar Alexander Birkner avatar Pedro Zigante avatar Renjie Xu avatar Alexander Ivanov avatar Eivind Siqveland Larsen avatar Steven Johnson avatar Noam Yogev avatar Aleš Bizjak avatar Lukas Himsel avatar Harish Srinivas avatar Yiling Yin avatar Nikita avatar Yota Hamada avatar  avatar  avatar Nash Tsai avatar  avatar CHEVALIER Arthur avatar leo. avatar axyie avatar Beny Muler avatar Daniel Ostrovsky avatar Dan Esparza avatar Can Evgin avatar M A avatar Eduardo Rabelo avatar David Wells avatar Robin Trietsch avatar  avatar  avatar ringsaturn avatar Marty avatar

Watchers

 avatar  avatar

grpc-docs's Issues

Is there something supposed to be here?

In the generated code for gendocu-public-apis, my run was encountering an issue because it expected some type of styling document?

ERROR in ../node_modules/gendocu-public-apis/sdk/ts/gendocu/documentation/v1/styling_pb.js Module build failed (from ./node_modules/source-map-loader/dist/cjs.js): Error: ENOENT: no such file or directory, open '/Users/willperacchio/Desktop/Code/API/gendocu/grpc-docs/node_modules/gendocu-public-apis/sdk/ts/gendocu/documentation/v1/styling_pb.js'

[BUG] `GRPCSelfGeneratedAPIReference` does not re-render when input props change

I'm using GRPCSelfGeneratedAPIReference component in a react app. The parent component pass down to GRPCSelfGeneratedAPIReference a path to a grpc json file using the file prop. The docs render correctly the first time, but once the file prop changes, the the docs aren't rendered.

You can reproduce this behaviour replacing example/App.tsx with the following code:

import React, { useState } from 'react'

// import { GRPCGenDocuAPIReference } from 'grpc-docs'
import { GRPCSelfGeneratedAPIReference } from 'grpc-docs'
// import exampleDefinition from './example-definition.json'

const App = () => {
  // return <GRPCGenDocuAPIReference project='LibraryApp' organization='gendocu' />
  // return <GRPCGenDocuAPIReference project='GendocuPublicApis' organization='gendocu' />

  // return  <GRPCSelfGeneratedAPIReference definition={JSON.stringify(exampleDefinition)} />

  const [coin, setCoin] = useState(0)
  const file =
    coin % 2 === 0
      ? '/example-descriptors/all-types.json'
      : '/example-descriptors/library-app.json'
  console.log('App: render with file', file)

  return (
    <div>
      <button onClick={() => setCoin(coin + 1)}>Change</button>
      <GRPCSelfGeneratedAPIReference file={file} />
    </div>
  )
}

export default App

I think it is needed to add file, scheme, definition to the dependencies of the following useEffect:

Package fails to install

Installing the grpc-docs package fails with this error:

GendocuPublicApis@https://git.gendocu.com/gendocu/GendocuPublicApis.git#commit=6e8d4c1d2342556a2e8e719f19385b266001ebae: Failed cloning the repository
   Repository URL: https://git.gendocu.com/gendocu/GendocuPublicApis.git
   Fatal Error: unable to access 'https://git.gendocu.com/gendocu/GendocuPublicApis.git/': server certificate verification failed. 

I'm using Yarn 4.0.2.

How to install dependenies?

Could you give an example on how to install required frontend dependencies and run the example? I was following this guide but encountered issues with installing dependencies for the frontend.

[BUG] Installing 'grpc-docs' NPM pacakge fails

Error message:

error Command failed.
Exit code: 128
Command: git
Arguments: ls-remote --tags --heads https://github.com/gendocu-com/gendocu-internal-apis
Directory: [....]
Output:
remote: Repository not found.
fatal: repository 'https://github.com/gendocu-com/gendocu-internal-apis/' not found
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

I think it's of it's dependency to https://www.npmjs.com/package/gendocu-internal-apis which seems to be a private package.

Not all dependencies are coming from well-known registry

Hey!

I am in the process to extend a well-known OSS project with a feature to be able to use this library and the protoc-gen-doc plugin to render your proto files in backstage.

You can check out the PR that would add this functionality here

However, for that project, it is a requirement that all the dependencies are coming from https://registry.npmjs.org/

Question

Is it possible to move the GendocuPublicApis to the npm registry?

 "GendocuPublicApis": "git+https://git.gendocu.com/gendocu/GendocuPublicApis.git#master"

Received error: SyntaxError: Unexpected token < in JSON at position 0

Hi, Thank you for great plugin, can you please help out with the issue ?
I am receiving Received error: SyntaxError: Unexpected token < in JSON at position 0 when using
<GRPCSelfGeneratedAPIReference file='../../../src/proto/description.json'/>
where description.json is a valid json file
thank you for your help and support

How do I use my own custom styles?

Hi there!
I've been using this library a lot, so first off, thank you!

I have a question regarding customizing styles.
The README suggests creating a style/my-style directory for custom styles, but where exactly should this directory be created? Should I create the my-style directory inside the node_modules/grpc-docs/src/style/default of the installed library within my project? Or is there another recommended method?

[BUG] HTML not rendering Enums

Overview

  • Enums are not displayed in the HTML page for a grpc api

ScreenShot

Screen Shot 2022-08-31 at 09 01 45

Protobuf

The service is near-minified:

// protobuf/test/v1/service.proto

syntax = "proto3";

package test.v1;
option java_package = "com.test.v1";

import "google/protobuf/any.proto";
import "protobuf/test/v1/model.proto";

// Service for testing.
service MyService {
    // Create a new something.
    rpc Create(CreateRequest) returns(CreateResponse);
}

message CreateResponse {
    // uh oh.
    string service_error = 2;
}

message CreateRequest {
    // something opaque.
    google.protobuf.Any who_knows = 1;

    test.v1.WhatToCreate what_to_create = 2;

    test.v1.TypeName type_name = 3;
}

// protobuf/test/v1/model.proto
syntax = "proto3";

package test.v1;
option java_package = "com.test.v1";

message WhatToCreate {
    // create this/me.
    string me = 1;
}


enum TypeName {
    TYPE_NAME_UNSPECIFIED = 0;

    // a blue type
    TYPE_NAME_BLUE = 1;

    // a yellow type
    TYPE_NAME_YELLOW = 2;
}

Here is the generated json from protoc-gen-doc:

{
  "files": [
    {
      "name": "protobuf/test/v1/model.proto",
      "description": "",
      "package": "test.v1",
      "hasEnums": true,
      "hasExtensions": false,
      "hasMessages": true,
      "hasServices": false,
      "enums": [
        {
          "name": "TypeName",
          "longName": "TypeName",
          "fullName": "test.v1.TypeName",
          "description": "",
          "values": [
            {
              "name": "TYPE_NAME_UNSPECIFIED",
              "number": "0",
              "description": ""
            },
            {
              "name": "TYPE_NAME_BLUE",
              "number": "1",
              "description": "a blue type"
            },
            {
              "name": "TYPE_NAME_YELLOW",
              "number": "2",
              "description": "a yellow type"
            }
          ]
        }
      ],
      "extensions": [],
      "messages": [
        {
          "name": "WhatToCreate",
          "longName": "WhatToCreate",
          "fullName": "test.v1.WhatToCreate",
          "description": "",
          "hasExtensions": false,
          "hasFields": true,
          "hasOneofs": false,
          "extensions": [],
          "fields": [
            {
              "name": "me",
              "description": "create this/me.",
              "label": "",
              "type": "string",
              "longType": "string",
              "fullType": "string",
              "ismap": false,
              "isoneof": false,
              "oneofdecl": "",
              "defaultValue": ""
            }
          ]
        }
      ],
      "services": []
    },
    {
      "name": "protobuf/test/v1/service.proto",
      "description": "",
      "package": "test.v1",
      "hasEnums": false,
      "hasExtensions": false,
      "hasMessages": true,
      "hasServices": true,
      "enums": [],
      "extensions": [],
      "messages": [
        {
          "name": "CreateRequest",
          "longName": "CreateRequest",
          "fullName": "test.v1.CreateRequest",
          "description": "",
          "hasExtensions": false,
          "hasFields": true,
          "hasOneofs": false,
          "extensions": [],
          "fields": [
            {
              "name": "who_knows",
              "description": "something opaque.",
              "label": "",
              "type": "Any",
              "longType": "google.protobuf.Any",
              "fullType": "google.protobuf.Any",
              "ismap": false,
              "isoneof": false,
              "oneofdecl": "",
              "defaultValue": ""
            },
            {
              "name": "what_to_create",
              "description": "",
              "label": "",
              "type": "WhatToCreate",
              "longType": "WhatToCreate",
              "fullType": "test.v1.WhatToCreate",
              "ismap": false,
              "isoneof": false,
              "oneofdecl": "",
              "defaultValue": ""
            },
            {
              "name": "type_name",
              "description": "",
              "label": "",
              "type": "TypeName",
              "longType": "TypeName",
              "fullType": "test.v1.TypeName",
              "ismap": false,
              "isoneof": false,
              "oneofdecl": "",
              "defaultValue": ""
            }
          ]
        },
        {
          "name": "CreateResponse",
          "longName": "CreateResponse",
          "fullName": "test.v1.CreateResponse",
          "description": "",
          "hasExtensions": false,
          "hasFields": true,
          "hasOneofs": false,
          "extensions": [],
          "fields": [
            {
              "name": "service_error",
              "description": "uh oh.",
              "label": "",
              "type": "string",
              "longType": "string",
              "fullType": "string",
              "ismap": false,
              "isoneof": false,
              "oneofdecl": "",
              "defaultValue": ""
            }
          ]
        }
      ],
      "services": [
        {
          "name": "MyService",
          "longName": "MyService",
          "fullName": "test.v1.MyService",
          "description": "Service for testing.",
          "methods": [
            {
              "name": "Create",
              "description": "Create a new something.",
              "requestType": "CreateRequest",
              "requestLongType": "CreateRequest",
              "requestFullType": "test.v1.CreateRequest",
              "requestStreaming": false,
              "responseType": "CreateResponse",
              "responseLongType": "CreateResponse",
              "responseFullType": "test.v1.CreateResponse",
              "responseStreaming": false
            }
          ]
        }
      ]
    }
  ],
  "scalarValueTypes": [
    {
      "protoType": "double",
      "notes": "",
      "cppType": "double",
      "csType": "double",
      "goType": "float64",
      "javaType": "double",
      "phpType": "float",
      "pythonType": "float",
      "rubyType": "Float"
    },
    {
      "protoType": "float",
      "notes": "",
      "cppType": "float",
      "csType": "float",
      "goType": "float32",
      "javaType": "float",
      "phpType": "float",
      "pythonType": "float",
      "rubyType": "Float"
    },
    {
      "protoType": "int32",
      "notes": "Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.",
      "cppType": "int32",
      "csType": "int",
      "goType": "int32",
      "javaType": "int",
      "phpType": "integer",
      "pythonType": "int",
      "rubyType": "Bignum or Fixnum (as required)"
    },
    {
      "protoType": "int64",
      "notes": "Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.",
      "cppType": "int64",
      "csType": "long",
      "goType": "int64",
      "javaType": "long",
      "phpType": "integer/string",
      "pythonType": "int/long",
      "rubyType": "Bignum"
    },
    {
      "protoType": "uint32",
      "notes": "Uses variable-length encoding.",
      "cppType": "uint32",
      "csType": "uint",
      "goType": "uint32",
      "javaType": "int",
      "phpType": "integer",
      "pythonType": "int/long",
      "rubyType": "Bignum or Fixnum (as required)"
    },
    {
      "protoType": "uint64",
      "notes": "Uses variable-length encoding.",
      "cppType": "uint64",
      "csType": "ulong",
      "goType": "uint64",
      "javaType": "long",
      "phpType": "integer/string",
      "pythonType": "int/long",
      "rubyType": "Bignum or Fixnum (as required)"
    },
    {
      "protoType": "sint32",
      "notes": "Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.",
      "cppType": "int32",
      "csType": "int",
      "goType": "int32",
      "javaType": "int",
      "phpType": "integer",
      "pythonType": "int",
      "rubyType": "Bignum or Fixnum (as required)"
    },
    {
      "protoType": "sint64",
      "notes": "Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.",
      "cppType": "int64",
      "csType": "long",
      "goType": "int64",
      "javaType": "long",
      "phpType": "integer/string",
      "pythonType": "int/long",
      "rubyType": "Bignum"
    },
    {
      "protoType": "fixed32",
      "notes": "Always four bytes. More efficient than uint32 if values are often greater than 2^28.",
      "cppType": "uint32",
      "csType": "uint",
      "goType": "uint32",
      "javaType": "int",
      "phpType": "integer",
      "pythonType": "int",
      "rubyType": "Bignum or Fixnum (as required)"
    },
    {
      "protoType": "fixed64",
      "notes": "Always eight bytes. More efficient than uint64 if values are often greater than 2^56.",
      "cppType": "uint64",
      "csType": "ulong",
      "goType": "uint64",
      "javaType": "long",
      "phpType": "integer/string",
      "pythonType": "int/long",
      "rubyType": "Bignum"
    },
    {
      "protoType": "sfixed32",
      "notes": "Always four bytes.",
      "cppType": "int32",
      "csType": "int",
      "goType": "int32",
      "javaType": "int",
      "phpType": "integer",
      "pythonType": "int",
      "rubyType": "Bignum or Fixnum (as required)"
    },
    {
      "protoType": "sfixed64",
      "notes": "Always eight bytes.",
      "cppType": "int64",
      "csType": "long",
      "goType": "int64",
      "javaType": "long",
      "phpType": "integer/string",
      "pythonType": "int/long",
      "rubyType": "Bignum"
    },
    {
      "protoType": "bool",
      "notes": "",
      "cppType": "bool",
      "csType": "bool",
      "goType": "bool",
      "javaType": "boolean",
      "phpType": "boolean",
      "pythonType": "boolean",
      "rubyType": "TrueClass/FalseClass"
    },
    {
      "protoType": "string",
      "notes": "A string must always contain UTF-8 encoded or 7-bit ASCII text.",
      "cppType": "string",
      "csType": "string",
      "goType": "string",
      "javaType": "String",
      "phpType": "string",
      "pythonType": "str/unicode",
      "rubyType": "String (UTF-8)"
    },
    {
      "protoType": "bytes",
      "notes": "May contain any arbitrary sequence of bytes.",
      "cppType": "string",
      "csType": "ByteString",
      "goType": "[]byte",
      "javaType": "ByteString",
      "phpType": "string",
      "pythonType": "str",
      "rubyType": "String (ASCII-8BIT)"
    }
  ]
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.