mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-21 06:55:03 +00:00
remove publisher
This commit is contained in:
@@ -1,38 +0,0 @@
|
|||||||
# API Publisher
|
|
||||||
|
|
||||||
The public api publisher for Micro services
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
The API publisher assumes a few things:
|
|
||||||
|
|
||||||
- Your service name is the directory of the service
|
|
||||||
- You have a `README.md` file we take as description
|
|
||||||
- You have a `make api` command to generate a `api-{service}.json` for the OpenAPI spec
|
|
||||||
- You optionally have a `publicapi.json` file to define extra info such a category, icon, etc
|
|
||||||
- You optionally have a `examples.json` file to separately define usage examples
|
|
||||||
- You optionaly have a `pricing.json` file to separately define pricing information
|
|
||||||
|
|
||||||
All these are combined to produce a Public API.
|
|
||||||
|
|
||||||
## Readme
|
|
||||||
|
|
||||||
The readmes are taken verbatim. Everything before the newline is used as a short excerpt. Examples are appended to your API
|
|
||||||
tab if they exist so no need to add random examples, curls, etc to the readme. Focus on describing the service in brevity.
|
|
||||||
|
|
||||||
## Comments
|
|
||||||
|
|
||||||
Some rules on how to write protos so they nicely appear in the output of this script:
|
|
||||||
|
|
||||||
- The request types (eg. `LoginRequest`) comments will be taken and used as a description for the endpoint (eg. `Login`) itself. This might change.
|
|
||||||
- The proto message field comments will be taken and displayed to craft them with care
|
|
||||||
|
|
||||||
To provide example values use the following format:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
// rss feed name
|
|
||||||
// eg. a16z
|
|
||||||
string name = 1;
|
|
||||||
```
|
|
||||||
|
|
||||||
The part after the `eg. ` until the newline will be used as example value.
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/getkin/kin-openapi/openapi3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PublicAPI struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Category string `json:"category,omitempty"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Icon string `json:"icon,omitempty"`
|
|
||||||
OpenAPIJson string `json:"open_api_json"`
|
|
||||||
Pricing map[string]int64 `json:"pricing,omitempty"`
|
|
||||||
ExamplesJson string `json:"examples_json,omitempty"`
|
|
||||||
PostmanJson string `json:"postman_json,omitempty"`
|
|
||||||
DisplayName string `json:"display_name,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
prodAPIDomain = "api.m3o.com"
|
|
||||||
)
|
|
||||||
|
|
||||||
func publishAPI(apiSpec *PublicAPI, domain string) error {
|
|
||||||
client := &http.Client{}
|
|
||||||
|
|
||||||
//Encode the data
|
|
||||||
postBody, _ := json.Marshal(map[string]interface{}{
|
|
||||||
"api": apiSpec,
|
|
||||||
})
|
|
||||||
|
|
||||||
rbody := bytes.NewBuffer(postBody)
|
|
||||||
|
|
||||||
//Leverage Go's HTTP Post function to make request
|
|
||||||
req, err := http.NewRequest("POST", fmt.Sprintf("https://%s/publicapi/Publish", domain), rbody)
|
|
||||||
|
|
||||||
// Add auth headers here if needed
|
|
||||||
req.Header.Add("Authorization", `Bearer `+os.Getenv("MICRO_ADMIN_TOKEN"))
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
|
||||||
b, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
return errors.New(string(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
io.Copy(ioutil.Discard, resp.Body)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
workDir, _ := os.Getwd()
|
|
||||||
domainFlag := flag.String("domain", prodAPIDomain, "domain to publish to e.g. api.m3o.com")
|
|
||||||
serviceFlag := flag.String("service", "", "individual service to publish e.g. helloworld")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
files, err := ioutil.ReadDir(flag.Arg(0))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
for _, f := range files {
|
|
||||||
if strings.Contains(f.Name(), "clients") || strings.Contains(f.Name(), "examples") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if len(*serviceFlag) > 0 && f.Name() != *serviceFlag {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if f.IsDir() && !strings.HasPrefix(f.Name(), ".") {
|
|
||||||
serviceDir := filepath.Join(workDir, f.Name())
|
|
||||||
serviceFiles, err := ioutil.ReadDir(serviceDir)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to read service dir", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
skip := false
|
|
||||||
for _, serviceFile := range serviceFiles {
|
|
||||||
if serviceFile.Name() == "skip" {
|
|
||||||
skip = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if skip {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Processing folder", serviceDir)
|
|
||||||
makeProto := exec.Command("make", "api")
|
|
||||||
makeProto.Dir = serviceDir
|
|
||||||
fmt.Println(serviceDir)
|
|
||||||
outp, err := makeProto.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to make api", string(outp))
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceName := f.Name()
|
|
||||||
|
|
||||||
// generate the Postman collection
|
|
||||||
postman := exec.Command("openapi2postmanv2", "-s", fmt.Sprintf("api-%s.json", serviceName), "-o", "postman.json")
|
|
||||||
postman.Dir = serviceDir
|
|
||||||
outp, err = postman.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Failed to generate postman collection %s %s\n", string(outp), err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
dat, err := ioutil.ReadFile(filepath.Join(serviceDir, "README.md"))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to read readme", string(outp))
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
apiJSON := filepath.Join(serviceDir, "api-"+serviceName+".json")
|
|
||||||
js, err := ioutil.ReadFile(apiJSON)
|
|
||||||
if err != nil {
|
|
||||||
apiJSON := filepath.Join(serviceDir, "api-protobuf.json")
|
|
||||||
js, err = ioutil.ReadFile(apiJSON)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to read json spec", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spec := &openapi3.Swagger{}
|
|
||||||
|
|
||||||
// we have to read an openapi spec otherwise we can't publish
|
|
||||||
if err := json.Unmarshal(js, &spec); err != nil {
|
|
||||||
fmt.Println("Failed to unmarshal", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// define the default public api values
|
|
||||||
publicApi := new(PublicAPI)
|
|
||||||
|
|
||||||
// if we find a public api definition we load it
|
|
||||||
if b, err := ioutil.ReadFile(filepath.Join(serviceDir, "publicapi.json")); err == nil {
|
|
||||||
// unpack the info if we read the file
|
|
||||||
json.Unmarshal(b, &publicApi)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we didn't get the default info from a file, populate it
|
|
||||||
if publicApi.Name == "" {
|
|
||||||
publicApi.Name = serviceName
|
|
||||||
}
|
|
||||||
if publicApi.Description == "" {
|
|
||||||
publicApi.Description = string(dat)
|
|
||||||
}
|
|
||||||
if publicApi.OpenAPIJson == "" {
|
|
||||||
publicApi.OpenAPIJson = string(js)
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the examples if they exist
|
|
||||||
if examples, err := ioutil.ReadFile(filepath.Join(serviceDir, "examples.json")); err == nil {
|
|
||||||
if len(examples) > 0 {
|
|
||||||
publicApi.ExamplesJson = string(examples)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the separate pricing if it exists
|
|
||||||
if pricingRaw, err := ioutil.ReadFile(filepath.Join(serviceDir, "pricing.json")); err == nil {
|
|
||||||
pricing := map[string]int64{}
|
|
||||||
// unmarshal the pricing info
|
|
||||||
if len(pricingRaw) > 0 {
|
|
||||||
json.Unmarshal(pricingRaw, &pricing)
|
|
||||||
publicApi.Pricing = pricing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the postman json
|
|
||||||
if postman, err := ioutil.ReadFile(filepath.Join(serviceDir, "postman.json")); err == nil {
|
|
||||||
if len(postman) > 0 {
|
|
||||||
publicApi.PostmanJson = string(postman)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// publish the api
|
|
||||||
if err := publishAPI(publicApi, *domainFlag); err != nil {
|
|
||||||
fmt.Println("Failed to save data to publicapi service", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user