1+ // Package simplapi provides a declarative HTTP API builder with optional
2+ // OpenAPI 3.1 spec generation. Use New with options to create an App, then
3+ // register routes via GET, POST, etc. and call ListenAndServe.
14package simplapi
25
36import (
@@ -8,38 +11,46 @@ import (
811 "github.com/go-simpl/simplapi/pkg/spec"
912)
1013
14+ // App is the main API builder. It holds a framework adapter, optional OpenAPI
15+ // spec, and a list of endpoints that are registered on Sync or ListenAndServe.
1116type App struct {
1217 framework framework.Framework
1318 spec * spec.Spec
1419
1520 endpoints []* Endpoint
1621}
1722
23+ // AppConfig holds options applied by AppOption functions during New.
1824type AppConfig struct {
1925 framework framework.Framework
2026 spec * spec.Spec
2127}
2228
29+ // AppOption configures an App at construction time (e.g. WithCreateFramework, WithAutoOpenAPISpec).
2330type AppOption func (* AppConfig )
2431
32+ // WithCreateFramework creates an App that uses the named framework (e.g. "fiber", "gin").
2533func WithCreateFramework (frameworkName string ) AppOption {
2634 return func (c * AppConfig ) {
2735 c .framework = framework .GetFramework (frameworkName )
2836 }
2937}
3038
39+ // WithFramework creates an App that uses the given framework instance.
3140func WithFramework (framework framework.Framework ) AppOption {
3241 return func (c * AppConfig ) {
3342 c .framework = framework
3443 }
3544}
3645
46+ // WithAutoOpenAPISpec enables OpenAPI 3.1 spec generation and built-in doc routes. basePkgName is stripped from schema type names.
3747func WithAutoOpenAPISpec (basePkgName string ) AppOption {
3848 return func (c * AppConfig ) {
3949 c .spec = spec .New (basePkgName )
4050 }
4151}
4252
53+ // New creates an App with the given options. If WithAutoOpenAPISpec is used, doc routes are registered immediately.
4354func New (opts ... AppOption ) * App {
4455 config := & AppConfig {}
4556 for _ , opt := range opts {
@@ -57,40 +68,48 @@ func New(opts ...AppOption) *App {
5768 return s
5869}
5970
71+ // GetApp returns the underlying framework (e.g. for middleware or testing).
6072func (s * App ) GetApp () framework.Framework {
6173 return s .framework
6274}
6375
76+ // GET registers a GET route; returns an Endpoint for fluent options (WithTag, WithoutSpec, etc.).
6477func (s * App ) GET (path string , handlers ... interface {}) * Endpoint {
6578 endpoint := newEndpoint (http .MethodGet , path , handlers ... )
6679 s .addEndpoint (endpoint )
6780 return endpoint
6881}
6982
83+ // POST registers a POST route; returns an Endpoint for fluent options.
7084func (s * App ) POST (path string , handlers ... interface {}) * Endpoint {
7185 endpoint := newEndpoint (http .MethodPost , path , handlers ... )
7286 s .addEndpoint (endpoint )
7387 return endpoint
7488}
7589
90+ // PUT registers a PUT route; returns an Endpoint for fluent options.
7691func (s * App ) PUT (path string , handlers ... interface {}) * Endpoint {
7792 endpoint := newEndpoint (http .MethodPut , path , handlers ... )
7893 s .addEndpoint (endpoint )
7994 return endpoint
8095}
8196
97+ // DELETE registers a DELETE route; returns an Endpoint for fluent options.
8298func (s * App ) DELETE (path string , handlers ... interface {}) * Endpoint {
8399 endpoint := newEndpoint (http .MethodDelete , path , handlers ... )
84100 s .addEndpoint (endpoint )
85101 return endpoint
86102}
87103
104+ // PATCH registers a PATCH route; returns an Endpoint for fluent options.
88105func (s * App ) PATCH (path string , handlers ... interface {}) * Endpoint {
89106 endpoint := newEndpoint (http .MethodPatch , path , handlers ... )
90107 s .addEndpoint (endpoint )
91108 return endpoint
92109}
93110
111+ // Sync registers all endpoints with the framework and (if enabled) the OpenAPI spec.
112+ // Registration is deferred until Sync or ListenAndServe so fluent options (WithTag, etc.) are applied first.
94113func (s * App ) Sync () {
95114 for _ , e := range s .endpoints {
96115 s .framework .Register (e .path , e .method , s .createHandler (e .handlers ... ))
@@ -100,8 +119,8 @@ func (s *App) Sync() {
100119 }
101120}
102121
122+ // ListenAndServe registers all endpoints with the framework then starts the server.
103123func (s * App ) ListenAndServe (addr string ) error {
104- // Actual registration of endpoints happen here
105124 s .Sync ()
106125
107126 return s .framework .ListenAndServe (addr )
@@ -112,7 +131,7 @@ func (s *App) addEndpoint(endpoint *Endpoint) {
112131}
113132
114133func (s * App ) createHandler (handlers ... interface {}) framework.FrameworkHandler {
115- // Reverse the handlers slice
134+ // Reverse so the first handler in the chain is outermost (middleware), last is innermost (route handler).
116135 for i , j := 0 , len (handlers )- 1 ; i < j ; i , j = i + 1 , j - 1 {
117136 handlers [i ], handlers [j ] = handlers [j ], handlers [i ]
118137 }
0 commit comments