// Build creates a new Route using the specification details collected by the RouteBuilder func (b *RouteBuilder) Build() Route { pathExpr, err := newPathExpression(b.currentPath) if err != nil { log.Printf("[restful] Invalid path:%s because:%v", b.currentPath, err) os.Exit(1) } if b.function == nil { log.Printf("[restful] No function specified for route:" + b.currentPath) os.Exit(1) } operationName := b.operation if len(operationName) == 0 && b.function != nil { // extract from definition operationName = nameOfFunction(b.function) } route := Route{ Method: b.httpMethod, Path: concatPath(b.rootPath, b.currentPath), Produces: b.produces, Consumes: b.consumes, Function: b.function, Filters: b.filters, relativePath: b.currentPath, pathExpr: pathExpr, Doc: b.doc, Notes: b.notes, Operation: operationName, ParameterDocs: b.parameters, ResponseErrors: b.errorMap, ReadSample: b.readSample, WriteSample: b.writeSample} route.postBuild() return route }
// compilePathExpression ensures that the path is compiled into a RegEx for those routers that need it. func (w *WebService) compilePathExpression() { if len(w.rootPath) == 0 { w.Path("/") // lazy initialize path } compiled, err := newPathExpression(w.rootPath) if err != nil { log.Printf("[restful] invalid path:%s because:%v", w.rootPath, err) os.Exit(1) } w.pathExpr = compiled }
// Add a WebService to the Container. It will detect duplicate root paths and panic in that case. func (c *Container) Add(service *WebService) *Container { c.webServicesLock.Lock() defer c.webServicesLock.Unlock() // If registered on root then no additional specific mapping is needed if !c.isRegisteredOnRoot { pattern := c.fixedPrefixPath(service.RootPath()) // check if root path registration is needed if "/" == pattern || "" == pattern { c.ServeMux.HandleFunc("/", c.dispatch) c.isRegisteredOnRoot = true } else { // detect if registration already exists alreadyMapped := false for _, each := range c.webServices { if each.RootPath() == service.RootPath() { alreadyMapped = true break } } if !alreadyMapped { c.ServeMux.HandleFunc(pattern, c.dispatch) if !strings.HasSuffix(pattern, "/") { c.ServeMux.HandleFunc(pattern+"/", c.dispatch) } } } } // cannot have duplicate root paths for _, each := range c.webServices { if each.RootPath() == service.RootPath() { log.Printf("[restful] WebService with duplicate root path detected:['%v']", each) os.Exit(1) } } // if rootPath was not set then lazy initialize it if len(service.rootPath) == 0 { service.Path("/") } c.webServices = append(c.webServices, service) return c }
type SwaggerService struct { config Config apiDeclarationMap *ApiDeclarationList } func newSwaggerService(config Config) *SwaggerService { return &SwaggerService{ config: config, apiDeclarationMap: new(ApiDeclarationList)} } // LogInfo is the function that is called when this package needs to log. It defaults to log.Printf var LogInfo = func(format string, v ...interface{}) { // use the restful package-wide logger log.Printf(format, v...) } // InstallSwaggerService add the WebService that provides the API documentation of all services // conform the Swagger documentation specifcation. (https://github.com/wordnik/swagger-core/wiki). func InstallSwaggerService(aSwaggerConfig Config) { RegisterSwaggerService(aSwaggerConfig, restful.DefaultContainer) } // RegisterSwaggerService add the WebService that provides the API documentation of all services // conform the Swagger documentation specifcation. (https://github.com/wordnik/swagger-core/wiki). func RegisterSwaggerService(config Config, wsContainer *restful.Container) { sws := newSwaggerService(config) ws := new(restful.WebService) ws.Path(config.ApiPath) ws.Produces(restful.MIME_JSON)