2d8f396eeb
Previously the base path for the API was hardcoded to `/api` and the specified version. This was not obvious that the generated code was setting that base path and it was not flexible for serving the API under a different path than `/api`. We will likely need to set a different base path if we pretend to serve the new back office API that we are going to implement alongside the current admin API until the new back office is fully implemented and verified that works properly. This commit also fix add the base path of the endpoints to the documentation because it was even more confusing for somebody that wants to use the API having to find out them through looking to the generated code. Change-Id: I6efab6b6f3d295129d6f42f7fbba8c2dc19725f4
91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
// Copyright (C) 2022 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package apigen
|
|
|
|
import (
|
|
"fmt"
|
|
"path"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"storj.io/storj/private/api"
|
|
)
|
|
|
|
// API represents specific API's configuration.
|
|
type API struct {
|
|
// Version is the corresponding version of the API.
|
|
// It's concatenated to the BasePath, so assuming the base path is "/api" and the version is "v1"
|
|
// the API paths will begin with `/api/v1`.
|
|
// When empty, the version doesn't appear in the API paths. If it starts or ends with one or more
|
|
// "/", they are stripped from the API endpoint paths.
|
|
Version string
|
|
Description string
|
|
// The package name to use for the Go generated code.
|
|
PackageName string
|
|
// BasePath is the base path for the API endpoints. E.g. "/api".
|
|
// It doesn't require to begin with "/". When empty, "/" is used.
|
|
BasePath string
|
|
Auth api.Auth
|
|
EndpointGroups []*EndpointGroup
|
|
}
|
|
|
|
// Group adds new endpoints group to API.
|
|
func (a *API) Group(name, prefix string) *EndpointGroup {
|
|
group := &EndpointGroup{
|
|
Name: name,
|
|
Prefix: prefix,
|
|
}
|
|
|
|
a.EndpointGroups = append(a.EndpointGroups, group)
|
|
|
|
return group
|
|
}
|
|
|
|
func (a *API) endpointBasePath() string {
|
|
if strings.HasPrefix(a.BasePath, "/") {
|
|
return path.Join(a.BasePath, a.Version)
|
|
}
|
|
|
|
return "/" + path.Join(a.BasePath, a.Version)
|
|
}
|
|
|
|
// StringBuilder is an extension of strings.Builder that allows for writing formatted lines.
|
|
type StringBuilder struct{ strings.Builder }
|
|
|
|
// Writelnf formats arguments according to a format specifier
|
|
// and appends the resulting string to the StringBuilder's buffer.
|
|
func (s *StringBuilder) Writelnf(format string, a ...interface{}) {
|
|
s.WriteString(fmt.Sprintf(format+"\n", a...))
|
|
}
|
|
|
|
// getElementaryType simplifies a Go type.
|
|
func getElementaryType(t reflect.Type) reflect.Type {
|
|
switch t.Kind() {
|
|
case reflect.Array, reflect.Chan, reflect.Ptr, reflect.Slice:
|
|
return getElementaryType(t.Elem())
|
|
default:
|
|
return t
|
|
}
|
|
}
|
|
|
|
// filter returns a new slice of reflect.Type values that satisfy the given keep function.
|
|
func filter(types []reflect.Type, keep func(reflect.Type) bool) []reflect.Type {
|
|
filtered := make([]reflect.Type, 0, len(types))
|
|
for _, t := range types {
|
|
if keep(t) {
|
|
filtered = append(filtered, t)
|
|
}
|
|
}
|
|
return filtered
|
|
}
|
|
|
|
// isNillableType returns whether instances of the given type can be nil.
|
|
func isNillableType(t reflect.Type) bool {
|
|
switch t.Kind() {
|
|
case reflect.Chan, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
|
return true
|
|
}
|
|
return false
|
|
}
|