-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gin support #4128
base: v3-alpha
Are you sure you want to change the base?
Gin support #4128
Conversation
…ontentTypeSniffer, for Gin (and other framework) compatibility.
Serve runtime from assetserver if requested.
Serve runtime from assetserver if requested. Add gin guide, fix asset server merge, add gin example adding http.CloseNotifier and http.Flusher interface to assetserver.contentTypeSniffer, for Gin (and other framework) compatibility.
WalkthroughThe changes update how a content type sniffer is instantiated in the asset server by replacing a composite literal with a dedicated constructor. A new constructor method and additional methods (close notification and flush support) have been added to enhance asset handling. Variable declaration syntax in the webview has been simplified. Additionally, multiple Gin examples and documentation have been updated, including routing adjustments, middleware improvements, API endpoints, event handling refinements, and expanded dependency versions. A new changelog entry and minor renamings in JavaScript and event emission functions complete the update. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Middleware
participant WailsHandler
participant GinRouter
Client->>Middleware: HTTP Request (URL)
alt URL starts with "/wails"
Middleware->>WailsHandler: Forward Request
else URL does not start with "/wails"
Middleware->>GinRouter: Pass Request
end
Note over Middleware: Decide routing based on URL prefix
sequenceDiagram
participant Client
participant EventEmitter
participant EventQueue
Client->>EventEmitter: Emit('eventName', data)
EventEmitter->>EventQueue: Dispatch event
EventQueue-->>EventEmitter: Event acknowledged
EventEmitter-->>Client: Return promise resolution
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 golangci-lint (1.62.2)Error: can't load config: the Go language version (go1.23) used to build golangci-lint is lower than the targeted Go version (1.24.0) ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (2)
v3/examples/gin-service/assets/index.html (1)
217-249
:⚠️ Potential issueDuplicated event handling code appears after the HTML closing tag.
There appears to be duplicated code after the closing HTML tag that should be removed. The duplicated section includes event listener setup that's already properly implemented in the script section.
- - // Use the Wails runtime to emit an event - matching the format in the events demo - const eventData = { - message: "Hello from the frontend!", - timestamp: new Date().toISOString() - }; - wails.Events.Emit({name: 'gin-api-event', data: eventData}); - }); - - // Set up event listener for responses from the backend - window.addEventListener('DOMContentLoaded', () => { - // Register event listener using Wails runtime - wails.Events.On("gin-api-response", (data) => { - document.getElementById('eventResponse').textContent = JSON.stringify(data, null, 2); - }); - - // Also listen for user-created events - wails.Events.On("user-created", (data) => { - document.getElementById('eventResponse').textContent = JSON.stringify({ - event: "user-created", - user: data - }, null, 2); - }); - - // Initial API call to get service info - fetchAPI('/info'); - }); - </script> -</body> -</html>v3/examples/gin-example/main.go (1)
110-114
:⚠️ Potential issueRemove duplicate code
Lines 110-114 appear to be duplicating the error handling code from lines 105-108. These lines should be removed.
// Run the app err := app.Run() if err != nil { log.Fatal(err) } } - err := app.Run() - if err != nil { - log.Fatal(err) - } -}
🧹 Nitpick comments (22)
mkdocs-website/docs/en/changelog.md (4)
20-37
: "Added" Section Provides Comprehensive DetailsThe "### Added" section lists the new features along with GitHub references and contributor attributions. This level of detail enhances traceability. For consistency, consider reviewing punctuation uniformity among bullet points.
38-71
: "Fixed" Section Thoroughly Documents Bug ResolutionsThe "### Fixed" section captures a wide range of fixes in detail, correlating GitHub pull requests with each change. Although repeating "Fixed" at the beginning of each bullet point is consistent with changelog conventions, you might explore slight rewording in a few entries to enhance readability.
🧰 Tools
🪛 LanguageTool
[style] ~46-~46: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...github.com//pull/2972). - Fixed application frozen when quit (Darwin) b...(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~49-~49: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...github.com//pull/2753). - Fixed hex values for arrow keys on Darwin by ...(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[grammar] ~54-~54: The operating system from Apple is written “macOS”.
Context: ... paths with spaces - @leaanthony. - Fix MacOS systray click handling when no attached...(MAC_OS)
[grammar] ~56-~56: “Windows” (operating system by Microsoft) is a proper noun and needs to be capitalized.
Context: ...ailsapp/wails/pull/3208) - Fix crash on windows left clicking the systray icon when not...(A_WINDOWS)
[grammar] ~56-~56: The verb “left-clicking” is spelled with a hyphen.
Context: ...wails/pull/3208) - Fix crash on windows left clicking the systray icon when not having an att...(CLICK_HYPHEN)
54-54
: Correct the Naming for macOSThe entry currently reads "Fix MacOS systray click handling..." Change "MacOS" to "macOS" to comply with standard naming conventions.
- - Fix MacOS systray click handling when no attached window by [thomas-senechal](https://github.com/thomas-senechal) in PR [#3207](https://github.com/wailsapp/wails/pull/3207) + - Fix macOS systray click handling when no attached window by [thomas-senechal](https://github.com/thomas-senechal) in PR [#3207](https://github.com/wailsapp/wails/pull/3207)🧰 Tools
🪛 LanguageTool
[grammar] ~54-~54: The operating system from Apple is written “macOS”.
Context: ... paths with spaces - @leaanthony. - Fix MacOS systray click handling when no attached...(MAC_OS)
56-56
: Improve Capitalization and Hyphenation for WindowsIn the entry "- Fix crash on windows left clicking the systray icon when not having an attached window...", update "windows" to "Windows" and change "left clicking" to "left-clicking" to maintain proper capitalization and readability.
- - Fix crash on windows left clicking the systray icon when not having an attached window [tw1nk](https://github.com/tw1nk) in PR [#3271](https://github.com/wailsapp/wails/pull/3271) + - Fix crash on Windows left-clicking the systray icon when not having an attached window [tw1nk](https://github.com/tw1nk) in PR [#3271](https://github.com/wailsapp/wails/pull/3271)🧰 Tools
🪛 LanguageTool
[grammar] ~56-~56: “Windows” (operating system by Microsoft) is a proper noun and needs to be capitalized.
Context: ...ailsapp/wails/pull/3208) - Fix crash on windows left clicking the systray icon when not...(A_WINDOWS)
[grammar] ~56-~56: The verb “left-clicking” is spelled with a hyphen.
Context: ...wails/pull/3208) - Fix crash on windows left clicking the systray icon when not having an att...(CLICK_HYPHEN)
v3/examples/gin-routing/README.md (1)
1-27
: Clear and Informative Documentation
This new README provides a concise overview and clear step-by-step instructions for using Gin as a router with Wails. As a minor nitpick, consider revising the list item “- Communicate between the Gin-served frontend and Wails backend” to “- Communicate between the Gin-served frontend and the Wails backend” for grammatical clarity.v3/examples/gin-routing/static/index.html (1)
1-95
: Well-Structured Integration Example with Minor Styling Suggestion
This HTML example effectively demonstrates the integration between Wails and Gin. The document layout clearly separates the event-triggering functionality and the API call example, and the inline JavaScript is well-organized with robust error handling. For improved maintainability in larger projects, consider externalizing the inline CSS into a dedicated stylesheet.v3/examples/gin-example/README.md (1)
12-12
: Minor grammatical suggestion.Consider adding the preposition "to" in this line for better readability.
-Communicate between the Gin-served frontend and Wails backend +Communicate between the Gin-served frontend and the Wails backend🧰 Tools
🪛 LanguageTool
[uncategorized] ~12-~12: Possible missing preposition found.
Context: ...d Gin - Define API endpoints with Gin - Communicate between the Gin-served frontend and Wai...(AI_HYDRA_LEO_MISSING_TO)
v3/examples/gin-routing/go.mod (1)
72-72
: Document the replacement directiveThe replacement directive points Wails to a local directory, which is appropriate for example code but should be documented in the README for clarity to users.
v3/examples/gin-routing/main.go (3)
32-53
: Good logging middleware implementationThe LoggingMiddleware provides useful request logging including method, path, client IP, status, and latency. This helps with debugging and monitoring.
Consider enhancing the logging middleware with:
- Configurable log levels
- Request body size information
- Optional logging format selection (e.g., JSON for structured logging)
-func LoggingMiddleware() gin.HandlerFunc { +func LoggingMiddleware(options ...LogOption) gin.HandlerFunc { + // Apply default options + opts := defaultLogOptions() + for _, opt := range options { + opt(opts) + } + return func(c *gin.Context) { // Start timer startTime := time.Now() // Process request c.Next() // Calculate latency latency := time.Since(startTime) + // Skip logging if below minimum level + if opts.minLevel > LogLevelInfo { + return + } + // Log request details - log.Printf("[GIN] %s | %s | %s | %d | %s", - c.Request.Method, - c.Request.URL.Path, - c.ClientIP(), - c.Writer.Status(), - latency, - ) + if opts.jsonFormat { + // JSON formatted log + log.Printf(`{"level":"info","component":"gin","method":"%s","path":"%s","ip":"%s","status":%d,"latency":"%s","size":%d}`, + c.Request.Method, c.Request.URL.Path, c.ClientIP(), c.Writer.Status(), latency, c.Writer.Size()) + } else { + // Plain text log + log.Printf("[GIN] %s | %s | %s | %d | %s | %d bytes", + c.Request.Method, c.Request.URL.Path, c.ClientIP(), c.Writer.Status(), latency, c.Writer.Size()) + } } }
68-74
: Add better error handling for static file servingWhile the current error handling returns a 500 error with a message, consider adding logging and more detailed error information for debugging purposes.
ginEngine.GET("/", func(c *gin.Context) { file, err := staticFiles.ReadFile("static/index.html") if err != nil { + log.Printf("ERROR: Failed to read index.html: %v", err) c.String(http.StatusInternalServerError, "Error reading index.html") return } c.Data(http.StatusOK, "text/html; charset=utf-8", file) })
97-99
: Consider enhancing event handlingThe event handler implementation is straightforward but could be enhanced with more structured logging and response capabilities.
app.OnEvent("gin-button-clicked", func(event *application.CustomEvent) { - log.Printf("Received event from frontend: %v", event.Data) + log.Printf("Received event from frontend: %v, sending acknowledgment", event.Data) + // Send acknowledgment back to frontend + app.Events.EmitTo("", "event-received", map[string]interface{}{ + "originalEvent": "gin-button-clicked", + "received": time.Now().Format(time.RFC3339), + }) })v3/examples/gin-service/go.mod (2)
6-7
: Consider consistency in Gin version across examplesThe gin-routing example uses Gin v1.9.1 while this example uses v1.10.0. For consistency across examples, consider using the same version unless there's a specific reason to use different versions.
74-74
: Document the replacement directiveThe replacement directive points Wails to a local directory, which is appropriate for example code but should be documented in the README for clarity to users.
v3/examples/gin-example/main.go (1)
61-68
: Improve error handling when reading index.htmlThe current error handling simply returns a 500 error with a message. Consider logging the actual error for debugging purposes.
ginEngine.GET("/", func(c *gin.Context) { file, err := staticFiles.ReadFile("static/index.html") if err != nil { + log.Printf("Error reading index.html: %v", err) c.String(http.StatusInternalServerError, "Error reading index.html") return } c.Data(http.StatusOK, "text/html; charset=utf-8", file) })
v3/internal/assetserver/content_type_sniffer.go (1)
120-134
: Add documentation comments to explain the purpose of these methodsThe implementation of
CloseNotify
,closeClient
, andFlush
methods is correct, but it would be helpful to add more detailed documentation comments to explain their purpose and usage.// CloseNotify implements the http.CloseNotifier interface. +// It returns a channel that receives a single value when the client connection has gone away. +// This can be used to cancel long operations on the server if the client disconnects. func (rw *contentTypeSniffer) CloseNotify() <-chan bool { return rw.closeChannel } +// closeClient sends a signal to the close channel to notify that the client connection has closed. +// This is typically called when detecting a client disconnect. func (rw *contentTypeSniffer) closeClient() { rw.closeChannel <- true } // Flush implements the http.Flusher interface. +// It flushes buffered data to the client if the underlying response writer supports it. +// This is useful for streaming responses or long-polling scenarios. func (rw *contentTypeSniffer) Flush() { if f, ok := rw.rw.(http.Flusher); ok { f.Flush() } }docs/src/content/docs/guides/gin-routing.mdx (1)
317-320
: Fix inconsistent event emission in example codeThe example code uses
ce.Events.Emit
but other examples in the documentation usewails.Events.Emit
. This could confuse users.document.getElementById('triggerEvent').addEventListener('click', () => { - ce.Events.Emit("my-event", { + wails.Events.Emit({name: "my-event", data: { message: "Hello from the frontend!", timestamp: new Date().toISOString() - }); + }}); });docs/src/content/docs/guides/gin.mdx (3)
34-47
: Middleware Example ClarityThe GinMiddleware example clearly demonstrates how to delegate requests: allowing Wails to handle the
/wails
route while passing all other requests to Gin. One suggestion is to consider whether an exact match (== "/wails"
) best serves your use case or if a more flexible check usingstrings.HasPrefix(r.URL.Path, "/wails")
might be more appropriate for handling sub-paths. This would align with the PR discussion about broader route matching in the actual implementation.
253-275
: Build Tags and Environment ConfigurationThe documentation now includes examples using build tags to manage Gin’s mode based on the environment. Consider updating the build tag examples to include the modern
//go:build
syntax (in addition to or instead of// +build
) for better compatibility with recent Go versions.
308-421
: Comprehensive Integration ExampleThe main function example integrates Gin with Wails effectively. It demonstrates the creation of a Gin router, the registration of custom middleware (including the GinMiddleware), static file serving using embedded assets, route definition for both HTML content and an API endpoint, and event handling with
app.OnEvent
. One minor suggestion is to consider usingstrings.HasPrefix
for the route check in the middleware to accommodate potential sub-paths beneath/wails
if that aligns with your design goals.v3/examples/gin-service/services/gin_service.go (3)
31-34
: EventData struct should include documentationConsider adding a comment to describe the purpose of the EventData struct and how it's used within the service. This would improve code clarity and documentation.
+// EventData represents the structure of event messages sent between frontend and backend type EventData struct { Message string `json:"message"` Timestamp string `json:"timestamp"` }
165-186
: Improve user deletion implementationThe current implementation has O(n) complexity and can be inefficient for large user lists. Also, the slice manipulation technique can potentially cause memory leaks by retaining references to removed users.
Consider using a more efficient approach:
// Delete a user users.DELETE("/:id", func(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } s.mu.Lock() defer s.mu.Unlock() - for i, user := range s.users { - if user.ID == id { - // Remove the user from the slice - s.users = append(s.users[:i], s.users[i+1:]...) - c.JSON(http.StatusOK, gin.H{"message": "User deleted"}) - return - } - } + found := false + newUsers := make([]User, 0, len(s.users)-1) + + for _, user := range s.users { + if user.ID == id { + found = true + continue + } + newUsers = append(newUsers, user) + } + + if found { + s.users = newUsers + c.JSON(http.StatusOK, gin.H{"message": "User deleted"}) + return + } c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) })
161-163
: Emit events after the mutex is unlockedThe event emission happens while the mutex is still locked, which could lead to unnecessary blocking, especially if event handling is slow.
Move the event emission after unlocking:
// Add to the users slice s.users = append(s.users, newUser) + // Get a copy of the user for the event + userCopy := newUser + c.JSON(http.StatusCreated, newUser) + s.mu.Unlock() + // Emit an event to notify about the new user - s.app.EmitEvent("user-created", newUser) + s.app.EmitEvent("user-created", userCopy) + + return })Then remove the
defer s.mu.Unlock()
line from earlier in the function.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
v3/examples/gin-example/go.sum
is excluded by!**/*.sum
v3/examples/gin-example/go.sum
is excluded by!**/*.sum
v3/examples/gin-service/go.sum
is excluded by!**/*.sum
v3/examples/gin-routing/go.sum
is excluded by!**/*.sum
📒 Files selected for processing (35)
v3/internal/assetserver/assetserver.go
(1 hunks)v3/internal/assetserver/assetserver_webview.go
(1 hunks)v3/internal/assetserver/content_type_sniffer.go
(2 hunks)mkdocs-website/docs/en/changelog.md
(1 hunks)v3/examples/gin-example/README.md
(1 hunks)v3/examples/gin-example/go.mod
(1 hunks)v3/examples/gin-example/main.go
(1 hunks)v3/examples/gin-example/static/index.html
(1 hunks)docs/src/content/docs/guides/gin.mdx
(1 hunks)docs/src/content/docs/guides/gin.mdx
(6 hunks)v3/examples/gin-example/go.mod
(1 hunks)v3/examples/gin-example/main.go
(2 hunks)v3/examples/gin-example/static/index.html
(1 hunks)v3/internal/assetserver/assetserver_webview.go
(1 hunks)docs/src/content/docs/guides/gin-routing.mdx
(2 hunks)docs/src/content/docs/guides/gin-services.mdx
(1 hunks)v3/examples/gin-example/main.go
(2 hunks)v3/examples/gin-example/static/index.html
(1 hunks)v3/examples/gin-service/assets/index.html
(1 hunks)v3/examples/gin-service/go.mod
(1 hunks)v3/examples/gin-service/main.go
(1 hunks)v3/examples/gin-service/services/gin_service.go
(1 hunks)v3/pkg/application/application.go
(2 hunks)docs/src/content/docs/guides/gin-routing.mdx
(1 hunks)docs/src/content/docs/guides/gin-services.mdx
(11 hunks)v3/examples/events/assets/index.html
(1 hunks)v3/examples/gin-routing/README.md
(1 hunks)v3/examples/gin-routing/go.mod
(1 hunks)v3/examples/gin-routing/main.go
(1 hunks)v3/examples/gin-routing/static/index.html
(1 hunks)v3/examples/gin-service/README.md
(1 hunks)v3/examples/gin-service/assets/index.html
(3 hunks)v3/internal/assetserver/bundledassets/runtime.js
(1 hunks)v3/internal/runtime/desktop/@wailsio/runtime/src/events.ts
(1 hunks)docs/src/content/docs/changelog.mdx
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
v3/examples/gin-service/README.md
[uncategorized] ~12-~12: Possible missing preposition found.
Context: ...d Gin - Define API endpoints with Gin - Communicate between the Gin-served frontend and Wai...
(AI_HYDRA_LEO_MISSING_TO)
v3/examples/gin-example/README.md
[uncategorized] ~12-~12: Possible missing preposition found.
Context: ...d Gin - Define API endpoints with Gin - Communicate between the Gin-served frontend and Wai...
(AI_HYDRA_LEO_MISSING_TO)
mkdocs-website/docs/en/changelog.md
[style] ~46-~46: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...github.com//pull/2972). - Fixed application frozen when quit (Darwin) b...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~49-~49: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...github.com//pull/2753). - Fixed hex values for arrow keys on Darwin by ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[grammar] ~54-~54: The operating system from Apple is written “macOS”.
Context: ... paths with spaces - @leaanthony. - Fix MacOS systray click handling when no attached...
(MAC_OS)
[grammar] ~56-~56: “Windows” (operating system by Microsoft) is a proper noun and needs to be capitalized.
Context: ...ailsapp/wails/pull/3208) - Fix crash on windows left clicking the systray icon when not...
(A_WINDOWS)
[grammar] ~56-~56: The verb “left-clicking” is spelled with a hyphen.
Context: ...wails/pull/3208) - Fix crash on windows left clicking the systray icon when not having an att...
(CLICK_HYPHEN)
🪛 Biome (1.9.4)
v3/internal/assetserver/bundledassets/runtime.js
[error] 1-1: This array contains an empty slot.
Unsafe fix: Replace hole with undefined
(lint/suspicious/noSparseArray)
[error] 1-1: Shouldn't redeclare 'i'. Consider to delete it or rename it.
'i' is defined here:
(lint/suspicious/noRedeclare)
[error] 1-1: This variable is used before its declaration.
The variable is declared here:
(lint/correctness/noInvalidUseBeforeDeclaration)
[error] 1-1: This variable is used before its declaration.
The variable is declared here:
(lint/correctness/noInvalidUseBeforeDeclaration)
[error] 1-1: Do not add then to a class.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Analyze (go)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (45)
mkdocs-website/docs/en/changelog.md (6)
1-2
: Changelog Header Looks CorrectThe top-level header is clearly defined and adheres to our established changelog format.
3-16
: Metadata and Format Comment Block is InformativeThe introductory comment block detailing the changelog conventions provides clear context. This helps new contributors understand the format and requirements.
18-19
: Unreleased Section Configured ProperlyThe use of the "## [Unreleased]" heading effectively distinguishes pending changes from released items.
72-82
: "Changed" Section Clearly Outlines API and Runtime UpdatesThis section details the modifications to the bundled JS runtime, the changes in API exposure, and adjustments to the binding generator. The information is detailed and clear, which helps in understanding the scope of these changes.
83-83
: Gin Support Enhancement Documented EffectivelyThe entry "- Modified the
contentTypeSniffer
struct to include thehttp.CloseNotifier
interface. Now compatible with Gin framework." is succinct and clearly signals the Gin support update. This directly aligns with the PR’s objective.
85-90
: Remaining Sections Appropriately Left BlankThe "Removed", "Deprecated", and "Security" sections are correctly empty, indicating there have been no removals, deprecations, or security fixes in this update.
v3/examples/events/assets/index.html (1)
12-12
: Simplified Event Emission Syntax
The updated callwails.Events.Emit('myevent', 'hello!')
aligns with the new API expectations and removes the previous object-based argument. Ensure that any event listeners are updated to expect two separate parameters rather than an object.docs/src/content/docs/changelog.mdx (1)
78-79
: Changelog Update for Gin Support
The changelog now includes a new entry for Gin support with proper attribution and PR reference. Please verify that all URLs and the PR identifiers match the intended documentation and that the attribution is consistent with earlier changelog conventions.v3/internal/assetserver/assetserver.go (1)
62-62
: Good refactoring to use a constructor function.This change improves encapsulation by replacing a direct struct initialization with a constructor call. This pattern makes initialization more standardized and easier to extend in the future.
v3/internal/assetserver/assetserver_webview.go (1)
77-77
: Good style improvement.Using the
:=
short variable declaration instead of explicit type declaration is more idiomatic Go and makes the code more concise while maintaining the same functionality.v3/examples/gin-example/static/index.html (2)
44-50
: Well-structured UI addition for Wails events demonstration.The new card with button for triggering Wails events is a good addition to demonstrate the integration between Gin and Wails event system.
58-93
: Good implementation of event handling.The JavaScript code correctly:
- Uses ES module syntax to import Wails runtime
- Sets up event listeners in a structured way
- Includes proper error handling
- Updates the UI to reflect event emission success or failure
This provides a good example of how to integrate Wails events in a Gin-based application.
v3/examples/gin-service/main.go (1)
1-45
: Well-structured example of Gin service integration.This example correctly demonstrates:
- Setting up a Wails application with proper configuration
- Integrating a Gin service with route configuration
- Configuring asset handling
- Creating a webview window with appropriate parameters
- Including proper error handling for application execution
The structure follows best practices for Wails applications and provides a good template for users looking to integrate Gin services.
v3/pkg/application/application.go (2)
9-9
: Good addition of the bundledassets import.The new import provides access to the runtime.js file needed for the Gin integration.
102-106
: Well implemented runtime.js route handling.This new case in the switch statement properly serves the Wails runtime JavaScript file needed for Gin integration. The error handling is thorough, using the application's fatal error handling mechanism.
v3/examples/gin-example/README.md (1)
1-105
: Well-structured Gin integration documentation.This README clearly explains how to integrate the Gin web framework with Wails applications. The organization is logical, with sections for overview, running examples, and explanations of how the integration works. The code examples are clear and well-commented.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~12-~12: Possible missing preposition found.
Context: ...d Gin - Define API endpoints with Gin - Communicate between the Gin-served frontend and Wai...(AI_HYDRA_LEO_MISSING_TO)
v3/examples/gin-service/assets/index.html (2)
110-216
: Well-implemented frontend integration with the Gin service.The JavaScript code effectively demonstrates interaction with the Gin API endpoints and proper use of the Wails runtime for event handling. The fetchAPI helper function, event listeners, and form handling follow good practices.
204-204
: Updated event emission syntax using the new API.This line correctly uses the new Events.Emit API format, which aligns with the changes made to the events.ts file in this PR.
v3/internal/runtime/desktop/@wailsio/runtime/src/events.ts (1)
127-145
: Well-designed enhancement to the Emit function for improved flexibility.The updated Emit function now provides a more flexible interface by supporting both the new parameter structure (name, data) and maintaining backward compatibility with the object-based approach. The type checking and conditional logic are well implemented.
v3/examples/gin-routing/go.mod (2)
6-8
: LGTM: Dependencies are clearly definedThe direct dependencies on Gin and Wails are appropriately specified with version numbers.
3-3
:✅ Verification successful
Confirm Go version compatibility with users
Go 1.24.0 is a very recent version which may not be widely adopted yet. Consider documenting this requirement clearly or updating to a more widely adopted version like 1.22.x for better compatibility.
🏁 Script executed:
#!/bin/bash # Check current stable Go version curl -s https://go.dev/VERSION?m=textLength of output: 76
Verified: Go version usage is appropriate.
Thego 1.24.0
directive inv3/examples/gin-routing/go.mod
aligns with the current stable release (observed as 1.24.1), so there is no immediate compatibility issue. However, to assist users who might be on older versions, it could be useful to document the minimum Go version requirement within the project’s documentation.v3/internal/assetserver/bundledassets/runtime.js (2)
76-76
: Variable naming changes in minified codeThe renaming of variable
W
tob
appears to be part of minification or code optimization. These changes shouldn't affect functionality as long as all references are updated consistently.
78-78
:❓ Verification inconclusive
Function renaming in minified code
The renaming of function
P
toD
seems to be part of code optimization. Ensure all references to this function throughout the codebase have been updated to maintain consistency.
🏁 Script executed:
#!/bin/bash # Check for any remaining references to function P that should be D rg "function P\(" --type jsLength of output: 50514
Action Required: Verify Consistent Function Renaming
In the updated file
v3/internal/assetserver/bundledassets/runtime.js
, the renaming appears to be applied correctly without lingering references to the old function nameP
. However, our search shows that inv2/internal/frontend/runtime/runtime_prod_desktop.js
there are still definitions and references usingfunction P(
. Please confirm whether these v2 implementations are legacy code not subject to the recent renaming or if they also require updates to useD
for consistency across the entire codebase.v3/examples/gin-routing/main.go (2)
17-30
: Well-designed middleware for routing between Wails and GinThe GinMiddleware implementation correctly routes requests between Wails and Gin based on path prefixes. This approach ensures that Wails-specific routes are handled by Wails while all other routes are handled by Gin.
91-93
: Good integration of Gin with Wails assetsThe approach of using Gin as both the asset handler and middleware is a clean way to integrate the frameworks. This makes routing seamless between Wails and Gin.
v3/examples/gin-service/go.mod (1)
3-3
:✅ Verification successful
Confirm Go version compatibility with users
Go 1.24.0 is a very recent version which may not be widely adopted yet. Consider documenting this requirement clearly or updating to a more widely adopted version like 1.22.x for better compatibility.
🏁 Script executed:
#!/bin/bash # Check current stable Go version curl -s https://go.dev/VERSION?m=textLength of output: 76
Go Version Compatibility Confirmed
The
go.mod
file inv3/examples/gin-service
specifiesgo 1.24.0
, which aligns well with the latest stable release (1.24.1 as verified). Since Go 1.24.x is now standard, it's acceptable to use this version. However, please consider adding documentation (e.g., in the README) to explicitly state that the module requires Go 1.24.x to ensure users are aware of the minimum version requirement.v3/internal/assetserver/content_type_sniffer.go (2)
7-12
: Good implementation of the constructorThe constructor correctly initializes the struct with a response writer and a buffered channel for close notifications.
20-20
: New field added correctlyThe
closeChannel
field is properly added to the struct to support close notifications.docs/src/content/docs/guides/gin-services.mdx (5)
8-16
: Well-structured introduction and outlineThe introduction clearly explains the purpose of integrating Gin with Wails, and the numbered list provides a good roadmap for the tutorial.
62-66
: Good addition of EventData structureThe EventData type is well-defined and will be useful for structured event communication between frontend and backend.
230-251
: Complete CRUD implementation with DELETE endpointThe DELETE endpoint implementation is correct and includes proper error handling for invalid IDs and cases where the user is not found.
488-507
: Comprehensive frontend implementation for user deletionThe implementation of the delete user functionality is thorough, including user prompting, error handling, and UI feedback.
389-404
: Well-designed user creation formThe user creation form is well-structured with proper input fields, labels, and buttons for submission and cancellation.
docs/src/content/docs/guides/gin-routing.mdx (4)
32-46
: Improved Wails route handlingGood update to use
strings.HasPrefix(r.URL.Path, "/wails")
instead of an exact path match. This correctly allows Wails to handle any routes under the "/wails" path, which is necessary for serving runtime files and handling events.
211-357
: Excellent addition of event communication documentationThe event communication section is comprehensive and provides clear guidance on enabling event communication between the frontend and backend. The code examples are well-structured and include proper error handling.
229-266
: Well-implemented GinService for serving Wails runtimeThe GinService struct and ServeHTTP method correctly implement handling for the Wails runtime.js file. The serveWailsRuntime method properly serves the runtime file with appropriate content type headers.
274-297
: Good implementation of event handling endpointThe event handling endpoint is well-designed and correctly bridges HTTP requests to the Wails event system. The JSON binding and error handling are properly implemented.
docs/src/content/docs/guides/gin.mdx (4)
3-10
: Header and Introduction UpdateChanging the section header from "Overview" to "Introduction" is a clear improvement that refocuses the guide as an introductory resource. Please ensure that any cross-references in the documentation are updated accordingly.
49-50
: Middleware Comment AdditionThe additional comment explaining that "This middleware passes all HTTP requests to the Gin router" is a helpful summary. No further action is required unless you wish to elaborate on edge-case routing scenarios.
209-222
: Event Handling UpdateThe revised event handler snippet now uses
app.OnEvent("my-event", func(event *application.CustomEvent) { ... })
which correctly reflects the updated API. Ensure that any other parts of the documentation referencing the oldapp.Events.On
syntax are similarly updated.
225-240
: JavaScript API Example ImprovementThe new JavaScript example demonstrating an API call to the
/api/hello
endpoint is well structured. The use of async/await, proper error handling, and clear DOM updates effectively communicates the intended functionality.v3/examples/gin-service/services/gin_service.go (1)
190-220
: Good implementation of logging middlewareThe logging middleware is well implemented, capturing important request details and properly using the application logger. It includes status code, method, path, client IP and latency which are essential for monitoring and debugging.
v3/examples/gin-example/go.mod (3)
10-70
: Security improvements from dependency updatesThe updates to security-related packages like
go-crypto
,circl
, andgolang.org/x/crypto
are beneficial as they likely include security fixes and improvements.
3-3
:❓ Verification inconclusive
Verify Go version compatibility with deployment targets
The Go version has been updated to 1.24.0, which is very recent. Make sure all development and deployment environments support this version before merging.
🌐 Web query:
When was Go 1.24.0 released? What's the current stable version of Go?
💡 Result:
Go 1.24.0 was released on February 11, 2025, as announced in the official release notes and developer communications[1][3][4][7]. The current stable version is Go 1.24.1, released on March 4, 2025, which includes security fixes for the
net/http
package and various bug fixes across the toolchain[2][5][6][10]. This follows Google's standard practice of maintaining two supported major releases, with Go 1.24 receiving updates until Go 1.26 is released[2][4].Citations:
- 1: https://tip.golang.org/doc/go1.24
- 2: https://endoflife.date/go
- 3: https://groups.google.com/g/golang-dev/c/ronuo6q16Sc
- 4: https://go.dev/doc/devel/release
- 5: https://en.wikipedia.org/wiki/Go_(programming_language)
- 6: https://go.dev/dl/
- 7: https://go.dev/blog/go1.24
- 8: https://www.webcreek.com/en/blog/software-development/top-10-most-popular-programming-languages-in-2025/
- 9: https://boldlygo.tech/archive/2025-02-11-go-1.24.0-is-here/
- 10: https://groups.google.com/g/golang-announce
- 11: https://dev.to/empiree/why-you-should-learn-go-in-2025-308l/comments
- 12: https://golangnugget.com/p/what-to-expect-from-go-1-24-part-1
- 13: https://antonz.org/go-1-24/
- 14: https://devblogs.microsoft.com/go/go-1-24-0-1-microsoft-build-now-available/
- 15: https://github.com/golang/go/milestone/322
- 16: doc: write release notes for Go 1.24 golang/go#68545
Action: Confirm Go version compatibility and consider aligning with the stable release
- The
go.mod
file atv3/examples/gin-example/go.mod
now specifies:go 1.24.0
- Note that Go 1.24.0 was released on February 11, 2025, while the current stable release is Go 1.24.1 (released on March 4, 2025).
- Please ensure that all development and deployment environments support Go 1.24.0, or consider updating to 1.24.1 if appropriate.
66-66
:❓ Verification inconclusive
Consider pinning to specific protobuf version
The update to
google.golang.org/protobuf v1.33.0
is a significant version jump. Protobuf changes can sometimes affect serialization compatibility.
🌐 Web query:
Are there any breaking changes in google.golang.org/protobuf v1.33.0? What security fixes does it include?
💡 Result:
The google.golang.org/protobuf v1.33.0 release primarily addresses security vulnerabilities while introducing one notable compatibility issue with older dependencies. Here's a breakdown:
Security Fixes
CVE-2024-24786:
- Vulnerability: The
protojson.Unmarshal
function could enter an infinite loop when unmarshaling invalid JSON inputs containinggoogle.protobuf.Any
values or when usingUnmarshalOptions.DiscardUnknown
[1][6][7].- Resolution: Unmarshaling now returns an error instead of looping indefinitely[1][6].
Compatibility Considerations
Breaking Change with Older Protobuf Modules:
v1.33.0 introduced incompatibility with the deprecatedgithub.com/golang/protobuf
module. Users of the older module must update togithub.com/golang/protobuf v1.5.4
to resolve this[2][5].Reflection API Stability:
While not directly breaking, the release emphasizes that internal implementation changes (e.g., reflection-based JSON/text serialization) may affect code relying on undocumented behavior[9][11].
Recommendations
- Update to v1.33.0 immediately if using
protojson
with untrusted inputs.- Migrate from
github.com/golang/protobuf
togoogle.golang.org/protobuf
where possible[5].- Verify compatibility with downstream dependencies (e.g., etcd, heimdall) that might require updates[10][14].
This release balances critical security fixes with minimal breaking changes, primarily affecting legacy integration scenarios.
Citations:
- 1: https://groups.google.com/g/golang-announce/c/ArQ6CDgtEjY
- 2: https://www.openwall.com/lists/oss-security/2024/03/08/4
- 3: https://github.com/protocolbuffers/protobuf-go/releases
- 4: https://github.com/dadrus/heimdall/blob/main/CHANGELOG.md
- 5: https://github.com/golang/protobuf/releases
- 6: https://pkg.go.dev/vuln/GO-2024-2611
- 7: https://groups.google.com/g/golang-announce/c/ArQ6CDgtEjY/
- 8: https://cloud.google.com/secret-manager/docs/release-notes
- 9: https://pkg.go.dev/google.golang.org/protobuf
- 10: Resolve CVE-2024-24786 etcd-io/etcd#17551
- 11: https://protobuf.dev/support/migration/
- 12: https://protobuf.dev/support/version-support/
- 13: https://buf.build/docs/bsr/tutorial/
- 14: https://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/merge_requests/276
- 15: https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go
- 16: https://grafana.com/docs/loki/latest/release-notes/v3-4/
- 17: https://pkg.go.dev/github.com/golang/protobuf
- 18: https://groups.google.com/g/golang-announce/search?q=%5Bsecurity%5D
- 19: https://protobuf.dev/downloads/
- 20: Latest version of google.golang.org/protobuf (v1.33.0) is no longer compatible with the latest version of github.com/golang/protobuf (v1.5.3) golang/protobuf#1596
Action Required: Verify and Pin Protobuf Dependency Version
The update to
google.golang.org/protobuf v1.33.0
brings important security fixes—most notably, it resolves CVE‑2024‑24786 by preventing infinite loops inprotojson.Unmarshal
. However, it also introduces a breaking change with respect to the deprecatedgithub.com/golang/protobuf
module. This could lead to compatibility issues if any parts of the codebase or downstream dependencies still expect the older API behavior.
- Review Dependency Compatibility: Ensure that no part of the project still relies on
github.com/golang/protobuf
. If so, confirm these dependencies are updated or managed appropriately.- Pinning Recommendation: Consider explicitly pinning the protobuf dependency in
go.mod
to avoid accidental version bumps that might reintroduce compatibility issues.- Check Internal API Usage: Verify that any internal implementations relying on undocumented reflection or serialization behaviors are not inadvertently affected by the changes in v1.33.0.
## Running the Example | ||
|
||
```bash | ||
cd v3/examples/gin-routing | ||
go mod tidy | ||
go run . | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directory Path Discrepancy in Running Instructions
The “Running the Example” section instructs users to navigate to v3/examples/gin-routing
, which appears to be a mistake since this file is for the Gin Service example. It is advisable to update the directory path to correctly reflect the example’s location (likely v3/examples/gin-service
).
- cd v3/examples/gin-routing
+ cd v3/examples/gin-service
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
## Running the Example | |
```bash | |
cd v3/examples/gin-routing | |
go mod tidy | |
go run . | |
``` | |
## Running the Example | |
// GinMiddleware creates a middleware that passes requests to Gin if they're not handled by Wails | ||
func GinMiddleware(ginEngine *gin.Engine) application.Middleware { | ||
return func(next http.Handler) http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
// Let Wails handle the `/wails` route | ||
if strings.HasPrefix(r.URL.Path, "/wails") { | ||
next.ServeHTTP(w, r) | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug in GinMiddleware: All requests are being passed to Gin
The current implementation passes all requests directly to Gin without first checking if Wails should handle them. This will prevent Wails from serving its runtime files at /wails/runtime.js
, which is necessary for frontend/backend communication.
Update the middleware to check for Wails routes first:
func GinMiddleware(ginEngine *gin.Engine) application.Middleware {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Let Wails handle the `/wails` route
+ if strings.HasPrefix(r.URL.Path, "/wails") {
+ next.ServeHTTP(w, r)
+ return
+ }
// Let Gin handle everything else
ginEngine.ServeHTTP(w, r)
})
}
}
Don't forget to add the import:
import (
"embed"
"log"
"net/http"
+ "strings"
"time"
"github.com/gin-gonic/gin"
"github.com/wailsapp/wails/v3/pkg/application"
)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// GinMiddleware creates a middleware that passes requests to Gin if they're not handled by Wails | |
func GinMiddleware(ginEngine *gin.Engine) application.Middleware { | |
return func(next http.Handler) http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
// Let Wails handle the `/wails` route | |
if strings.HasPrefix(r.URL.Path, "/wails") { | |
next.ServeHTTP(w, r) | |
return | |
// --- Updated Import Block --- | |
import ( | |
"embed" | |
"log" | |
"net/http" | |
"strings" // Added import for strings | |
"time" | |
"github.com/gin-gonic/gin" | |
"github.com/wailsapp/wails/v3/pkg/application" | |
) | |
// --- Updated GinMiddleware Function --- | |
func GinMiddleware(ginEngine *gin.Engine) application.Middleware { | |
return func(next http.Handler) http.Handler { | |
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
// Let Wails handle the `/wails` route | |
if strings.HasPrefix(r.URL.Path, "/wails") { | |
next.ServeHTTP(w, r) | |
return | |
} | |
// Let Gin handle everything else | |
ginEngine.ServeHTTP(w, r) | |
}) | |
} | |
} |
// Create a new user | ||
users.POST("", func(c *gin.Context) { | ||
var newUser User | ||
if err := c.ShouldBindJSON(&newUser); err != nil { | ||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) | ||
return | ||
} | ||
|
||
s.mu.Lock() | ||
defer s.mu.Unlock() | ||
|
||
// Set the ID and creation time | ||
newUser.ID = s.nextID | ||
newUser.CreatedAt = time.Now() | ||
s.nextID++ | ||
|
||
// Add to the users slice | ||
s.users = append(s.users, newUser) | ||
|
||
c.JSON(http.StatusCreated, newUser) | ||
|
||
// Emit an event to notify about the new user | ||
s.app.EmitEvent("user-created", newUser) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation for user creation
The POST endpoint for creating a user doesn't validate that required fields (like name and email) are provided and properly formatted before adding the user to the system.
Add validation to ensure data integrity:
// Create a new user
users.POST("", func(c *gin.Context) {
var newUser User
if err := c.ShouldBindJSON(&newUser); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
+
+ // Validate required fields
+ if newUser.Name == "" {
+ c.JSON(http.StatusBadRequest, gin.H{"error": "Name is required"})
+ return
+ }
+ if newUser.Email == "" {
+ c.JSON(http.StatusBadRequest, gin.H{"error": "Email is required"})
+ return
+ }
+ // Basic email validation (consider using a proper validator library in production)
+ if !strings.Contains(newUser.Email, "@") {
+ c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid email format"})
+ return
+ }
s.mu.Lock()
defer s.mu.Unlock()
Don't forget to add the strings import:
import (
"context"
"net/http"
"strconv"
+ "strings"
"sync"
"time"
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// Create a new user | |
users.POST("", func(c *gin.Context) { | |
var newUser User | |
if err := c.ShouldBindJSON(&newUser); err != nil { | |
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) | |
return | |
} | |
s.mu.Lock() | |
defer s.mu.Unlock() | |
// Set the ID and creation time | |
newUser.ID = s.nextID | |
newUser.CreatedAt = time.Now() | |
s.nextID++ | |
// Add to the users slice | |
s.users = append(s.users, newUser) | |
c.JSON(http.StatusCreated, newUser) | |
// Emit an event to notify about the new user | |
s.app.EmitEvent("user-created", newUser) | |
}) | |
// import block (ensure this exists in your file) | |
import ( | |
"context" | |
"net/http" | |
"strconv" | |
"strings" | |
"sync" | |
"time" | |
) | |
// ... | |
// Create a new user | |
users.POST("", func(c *gin.Context) { | |
var newUser User | |
if err := c.ShouldBindJSON(&newUser); err != nil { | |
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) | |
return | |
} | |
// Validate required fields | |
if newUser.Name == "" { | |
c.JSON(http.StatusBadRequest, gin.H{"error": "Name is required"}) | |
return | |
} | |
if newUser.Email == "" { | |
c.JSON(http.StatusBadRequest, gin.H{"error": "Email is required"}) | |
return | |
} | |
// Basic email validation (consider using a proper validator library in production) | |
if !strings.Contains(newUser.Email, "@") { | |
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid email format"}) | |
return | |
} | |
s.mu.Lock() | |
defer s.mu.Unlock() | |
// Set the ID and creation time | |
newUser.ID = s.nextID | |
newUser.CreatedAt = time.Now() | |
s.nextID++ | |
// Add to the users slice | |
s.users = append(s.users, newUser) | |
c.JSON(http.StatusCreated, newUser) | |
// Emit an event to notify about the new user | |
s.app.EmitEvent("user-created", newUser) | |
}) |
func (s *GinService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { | ||
// You can access the application instance via ctx | ||
s.app = application.Get() | ||
|
||
// Register an event handler that can be triggered from the frontend | ||
s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) { | ||
// Log the event data | ||
// Parse the event data | ||
s.app.Logger.Info("Received event from frontend", "data", event.Data) | ||
|
||
// You could also emit an event back to the frontend | ||
s.app.EmitEvent("gin-api-response", map[string]interface{}{ | ||
"message": "Response from Gin API Service", | ||
"time": time.Now().Format(time.RFC3339), | ||
}) | ||
}) | ||
|
||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The app field is accessed in routes before being initialized
The app field is only initialized in ServiceStartup but is used in setupRoutes (called during NewGinService). If ServeHTTP is called before ServiceStartup, the app reference could be nil when the user creation route is accessed.
Consider refactoring initialization to ensure the app is available when needed:
func NewGinService() *GinService {
// Create a new Gin router
ginEngine := gin.New()
// Add middlewares
ginEngine.Use(gin.Recovery())
ginEngine.Use(LoggingMiddleware())
service := &GinService{
ginEngine: ginEngine,
users: []User{
{ID: 1, Name: "Alice", Email: "alice@example.com", CreatedAt: time.Now().Add(-72 * time.Hour)},
{ID: 2, Name: "Bob", Email: "bob@example.com", CreatedAt: time.Now().Add(-48 * time.Hour)},
{ID: 3, Name: "Charlie", Email: "charlie@example.com", CreatedAt: time.Now().Add(-24 * time.Hour)},
},
nextID: 4,
+ app: application.Get(),
}
// Define routes
service.setupRoutes()
return service
}
Then update ServiceStartup accordingly:
// ServiceStartup is called when the service starts
func (s *GinService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
- // You can access the application instance via ctx
- s.app = application.Get()
+ // Verify we have access to the application
+ if s.app == nil {
+ s.app = application.Get()
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
func (s *GinService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { | |
// You can access the application instance via ctx | |
s.app = application.Get() | |
// Register an event handler that can be triggered from the frontend | |
s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) { | |
// Log the event data | |
// Parse the event data | |
s.app.Logger.Info("Received event from frontend", "data", event.Data) | |
// You could also emit an event back to the frontend | |
s.app.EmitEvent("gin-api-response", map[string]interface{}{ | |
"message": "Response from Gin API Service", | |
"time": time.Now().Format(time.RFC3339), | |
}) | |
}) | |
return nil | |
} | |
// NewGinService initializes a new GinService instance | |
func NewGinService() *GinService { | |
// Create a new Gin router | |
ginEngine := gin.New() | |
// Add middlewares | |
ginEngine.Use(gin.Recovery()) | |
ginEngine.Use(LoggingMiddleware()) | |
service := &GinService{ | |
ginEngine: ginEngine, | |
users: []User{ | |
{ID: 1, Name: "Alice", Email: "alice@example.com", CreatedAt: time.Now().Add(-72 * time.Hour)}, | |
{ID: 2, Name: "Bob", Email: "bob@example.com", CreatedAt: time.Now().Add(-48 * time.Hour)}, | |
{ID: 3, Name: "Charlie", Email: "charlie@example.com", CreatedAt: time.Now().Add(-24 * time.Hour)}, | |
}, | |
nextID: 4, | |
app: application.Get(), // Initialize the app to ensure it's available in routes | |
} | |
// Define routes | |
service.setupRoutes() | |
return service | |
} |
func (s *GinService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { | |
// You can access the application instance via ctx | |
s.app = application.Get() | |
// Register an event handler that can be triggered from the frontend | |
s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) { | |
// Log the event data | |
// Parse the event data | |
s.app.Logger.Info("Received event from frontend", "data", event.Data) | |
// You could also emit an event back to the frontend | |
s.app.EmitEvent("gin-api-response", map[string]interface{}{ | |
"message": "Response from Gin API Service", | |
"time": time.Now().Format(time.RFC3339), | |
}) | |
}) | |
return nil | |
} | |
// ServiceStartup is called when the service starts | |
func (s *GinService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error { | |
// Verify we have access to the application | |
if s.app == nil { | |
s.app = application.Get() | |
} | |
// Register an event handler that can be triggered from the frontend | |
s.app.OnEvent("gin-api-event", func(event *application.CustomEvent) { | |
// Log the event data | |
// Parse the event data | |
s.app.Logger.Info("Received event from frontend", "data", event.Data) | |
// You could also emit an event back to the frontend | |
s.app.EmitEvent("gin-api-response", map[string]interface{}{ | |
"message": "Response from Gin API Service", | |
"time": time.Now().Format(time.RFC3339), | |
}) | |
}) | |
return nil | |
} |
This PR contains:
Based on the original PR here: #3537
Summary by CodeRabbit