Преглед изворни кода

refactor(api): rename API handlers for consistency

Frédéric Guillot пре 3 недеља
родитељ
комит
6276d7e69b

+ 49 - 64
internal/api/api.go

@@ -5,11 +5,8 @@ package api // import "miniflux.app/v2/internal/api"
 
 import (
 	"net/http"
-	"runtime"
 
-	"miniflux.app/v2/internal/http/response"
 	"miniflux.app/v2/internal/storage"
-	"miniflux.app/v2/internal/version"
 	"miniflux.app/v2/internal/worker"
 
 	"github.com/gorilla/mux"
@@ -31,66 +28,54 @@ func Serve(router *mux.Router, store *storage.Storage, pool *worker.Pool) {
 	sr.Use(middleware.apiKeyAuth)
 	sr.Use(middleware.basicAuth)
 	sr.Methods(http.MethodOptions)
-	sr.HandleFunc("/users", handler.createUser).Methods(http.MethodPost)
-	sr.HandleFunc("/users", handler.users).Methods(http.MethodGet)
-	sr.HandleFunc("/users/{userID:[0-9]+}", handler.userByID).Methods(http.MethodGet)
-	sr.HandleFunc("/users/{userID:[0-9]+}", handler.updateUser).Methods(http.MethodPut)
-	sr.HandleFunc("/users/{userID:[0-9]+}", handler.removeUser).Methods(http.MethodDelete)
-	sr.HandleFunc("/users/{userID:[0-9]+}/mark-all-as-read", handler.markUserAsRead).Methods(http.MethodPut)
-	sr.HandleFunc("/users/{username}", handler.userByUsername).Methods(http.MethodGet)
-	sr.HandleFunc("/me", handler.currentUser).Methods(http.MethodGet)
-	sr.HandleFunc("/categories", handler.createCategory).Methods(http.MethodPost)
-	sr.HandleFunc("/categories", handler.getCategories).Methods(http.MethodGet)
-	sr.HandleFunc("/categories/{categoryID}", handler.updateCategory).Methods(http.MethodPut)
-	sr.HandleFunc("/categories/{categoryID}", handler.removeCategory).Methods(http.MethodDelete)
-	sr.HandleFunc("/categories/{categoryID}/mark-all-as-read", handler.markCategoryAsRead).Methods(http.MethodPut)
-	sr.HandleFunc("/categories/{categoryID}/feeds", handler.getCategoryFeeds).Methods(http.MethodGet)
-	sr.HandleFunc("/categories/{categoryID}/refresh", handler.refreshCategory).Methods(http.MethodPut)
-	sr.HandleFunc("/categories/{categoryID}/entries", handler.getCategoryEntries).Methods(http.MethodGet)
-	sr.HandleFunc("/categories/{categoryID}/entries/{entryID}", handler.getCategoryEntry).Methods(http.MethodGet)
-	sr.HandleFunc("/discover", handler.discoverSubscriptions).Methods(http.MethodPost)
-	sr.HandleFunc("/feeds", handler.createFeed).Methods(http.MethodPost)
-	sr.HandleFunc("/feeds", handler.getFeeds).Methods(http.MethodGet)
-	sr.HandleFunc("/feeds/counters", handler.fetchCounters).Methods(http.MethodGet)
-	sr.HandleFunc("/feeds/refresh", handler.refreshAllFeeds).Methods(http.MethodPut)
-	sr.HandleFunc("/feeds/{feedID}/refresh", handler.refreshFeed).Methods(http.MethodPut)
-	sr.HandleFunc("/feeds/{feedID}", handler.getFeed).Methods(http.MethodGet)
-	sr.HandleFunc("/feeds/{feedID}", handler.updateFeed).Methods(http.MethodPut)
-	sr.HandleFunc("/feeds/{feedID}", handler.removeFeed).Methods(http.MethodDelete)
-	sr.HandleFunc("/feeds/{feedID}/icon", handler.getIconByFeedID).Methods(http.MethodGet)
-	sr.HandleFunc("/feeds/{feedID}/mark-all-as-read", handler.markFeedAsRead).Methods(http.MethodPut)
-	sr.HandleFunc("/export", handler.exportFeeds).Methods(http.MethodGet)
-	sr.HandleFunc("/import", handler.importFeeds).Methods(http.MethodPost)
-	sr.HandleFunc("/feeds/{feedID}/entries", handler.getFeedEntries).Methods(http.MethodGet)
-	sr.HandleFunc("/feeds/{feedID}/entries/import", handler.importFeedEntry).Methods(http.MethodPost)
-	sr.HandleFunc("/feeds/{feedID}/entries/{entryID}", handler.getFeedEntry).Methods(http.MethodGet)
-	sr.HandleFunc("/entries", handler.getEntries).Methods(http.MethodGet)
-	sr.HandleFunc("/entries", handler.setEntryStatus).Methods(http.MethodPut)
-	sr.HandleFunc("/entries/{entryID}", handler.getEntry).Methods(http.MethodGet)
-	sr.HandleFunc("/entries/{entryID}", handler.updateEntry).Methods(http.MethodPut)
-	sr.HandleFunc("/entries/{entryID}/bookmark", handler.toggleStarred).Methods(http.MethodPut)
-	sr.HandleFunc("/entries/{entryID}/star", handler.toggleStarred).Methods(http.MethodPut)
-	sr.HandleFunc("/entries/{entryID}/save", handler.saveEntry).Methods(http.MethodPost)
-	sr.HandleFunc("/entries/{entryID}/fetch-content", handler.fetchContent).Methods(http.MethodGet)
-	sr.HandleFunc("/flush-history", handler.flushHistory).Methods(http.MethodPut, http.MethodDelete)
-	sr.HandleFunc("/icons/{iconID}", handler.getIconByIconID).Methods(http.MethodGet)
-	sr.HandleFunc("/enclosures/{enclosureID}", handler.getEnclosureByID).Methods(http.MethodGet)
-	sr.HandleFunc("/enclosures/{enclosureID}", handler.updateEnclosureByID).Methods(http.MethodPut)
-	sr.HandleFunc("/integrations/status", handler.getIntegrationsStatus).Methods(http.MethodGet)
+	sr.HandleFunc("/users", handler.createUserHandler).Methods(http.MethodPost)
+	sr.HandleFunc("/users", handler.usersHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/users/{userID:[0-9]+}", handler.userByIDHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/users/{userID:[0-9]+}", handler.updateUserHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/users/{userID:[0-9]+}", handler.removeUserHandler).Methods(http.MethodDelete)
+	sr.HandleFunc("/users/{userID:[0-9]+}/mark-all-as-read", handler.markUserAsReadHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/users/{username}", handler.userByUsernameHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/me", handler.currentUserHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/categories", handler.createCategoryHandler).Methods(http.MethodPost)
+	sr.HandleFunc("/categories", handler.getCategoriesHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/categories/{categoryID}", handler.updateCategoryHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/categories/{categoryID}", handler.removeCategoryHandler).Methods(http.MethodDelete)
+	sr.HandleFunc("/categories/{categoryID}/mark-all-as-read", handler.markCategoryAsReadHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/categories/{categoryID}/feeds", handler.getCategoryFeedsHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/categories/{categoryID}/refresh", handler.refreshCategoryHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/categories/{categoryID}/entries", handler.getCategoryEntriesHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/categories/{categoryID}/entries/{entryID}", handler.getCategoryEntryHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/discover", handler.discoverSubscriptionsHandler).Methods(http.MethodPost)
+	sr.HandleFunc("/feeds", handler.createFeedHandler).Methods(http.MethodPost)
+	sr.HandleFunc("/feeds", handler.getFeedsHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/feeds/counters", handler.fetchCountersHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/feeds/refresh", handler.refreshAllFeedsHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/feeds/{feedID}/refresh", handler.refreshFeedHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/feeds/{feedID}", handler.getFeedHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/feeds/{feedID}", handler.updateFeedHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/feeds/{feedID}", handler.removeFeedHandler).Methods(http.MethodDelete)
+	sr.HandleFunc("/feeds/{feedID}/icon", handler.getIconByFeedIDHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/feeds/{feedID}/mark-all-as-read", handler.markFeedAsReadHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/export", handler.exportFeedsHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/import", handler.importFeedsHandler).Methods(http.MethodPost)
+	sr.HandleFunc("/feeds/{feedID}/entries", handler.getFeedEntriesHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/feeds/{feedID}/entries/import", handler.importFeedEntryHandler).Methods(http.MethodPost)
+	sr.HandleFunc("/feeds/{feedID}/entries/{entryID}", handler.getFeedEntryHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/entries", handler.getEntriesHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/entries", handler.setEntryStatusHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/entries/{entryID}", handler.getEntryHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/entries/{entryID}", handler.updateEntryHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/entries/{entryID}/bookmark", handler.toggleStarredHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/entries/{entryID}/star", handler.toggleStarredHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/entries/{entryID}/save", handler.saveEntryHandler).Methods(http.MethodPost)
+	sr.HandleFunc("/entries/{entryID}/fetch-content", handler.fetchContentHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/flush-history", handler.flushHistoryHandler).Methods(http.MethodPut, http.MethodDelete)
+	sr.HandleFunc("/icons/{iconID}", handler.getIconByIconIDHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/enclosures/{enclosureID}", handler.getEnclosureByIDHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/enclosures/{enclosureID}", handler.updateEnclosureByIDHandler).Methods(http.MethodPut)
+	sr.HandleFunc("/integrations/status", handler.getIntegrationsStatusHandler).Methods(http.MethodGet)
 	sr.HandleFunc("/version", handler.versionHandler).Methods(http.MethodGet)
-	sr.HandleFunc("/api-keys", handler.createAPIKey).Methods(http.MethodPost)
-	sr.HandleFunc("/api-keys", handler.getAPIKeys).Methods(http.MethodGet)
-	sr.HandleFunc("/api-keys/{apiKeyID}", handler.deleteAPIKey).Methods(http.MethodDelete)
-}
-
-func (h *handler) versionHandler(w http.ResponseWriter, r *http.Request) {
-	response.JSON(w, r, &versionResponse{
-		Version:   version.Version,
-		Commit:    version.Commit,
-		BuildDate: version.BuildDate,
-		GoVersion: runtime.Version(),
-		Compiler:  runtime.Compiler,
-		Arch:      runtime.GOARCH,
-		OS:        runtime.GOOS,
-	})
+	sr.HandleFunc("/api-keys", handler.createAPIKeyHandler).Methods(http.MethodPost)
+	sr.HandleFunc("/api-keys", handler.getAPIKeysHandler).Methods(http.MethodGet)
+	sr.HandleFunc("/api-keys/{apiKeyID}", handler.deleteAPIKeyHandler).Methods(http.MethodDelete)
 }

+ 3 - 3
internal/api/api_key.go → internal/api/api_key_handlers.go

@@ -15,7 +15,7 @@ import (
 	"miniflux.app/v2/internal/validator"
 )
 
-func (h *handler) createAPIKey(w http.ResponseWriter, r *http.Request) {
+func (h *handler) createAPIKeyHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 
 	var apiKeyCreationRequest model.APIKeyCreationRequest
@@ -38,7 +38,7 @@ func (h *handler) createAPIKey(w http.ResponseWriter, r *http.Request) {
 	response.JSONCreated(w, r, apiKey)
 }
 
-func (h *handler) getAPIKeys(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getAPIKeysHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 	apiKeys, err := h.store.APIKeys(userID)
 	if err != nil {
@@ -48,7 +48,7 @@ func (h *handler) getAPIKeys(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, apiKeys)
 }
 
-func (h *handler) deleteAPIKey(w http.ResponseWriter, r *http.Request) {
+func (h *handler) deleteAPIKeyHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 	apiKeyID := request.RouteInt64Param(r, "apiKeyID")
 

+ 6 - 6
internal/api/category.go → internal/api/category_handlers.go

@@ -16,7 +16,7 @@ import (
 	"miniflux.app/v2/internal/validator"
 )
 
-func (h *handler) createCategory(w http.ResponseWriter, r *http.Request) {
+func (h *handler) createCategoryHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 
 	var categoryCreationRequest model.CategoryCreationRequest
@@ -39,7 +39,7 @@ func (h *handler) createCategory(w http.ResponseWriter, r *http.Request) {
 	response.JSONCreated(w, r, category)
 }
 
-func (h *handler) updateCategory(w http.ResponseWriter, r *http.Request) {
+func (h *handler) updateCategoryHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 	categoryID := request.RouteInt64Param(r, "categoryID")
 
@@ -75,7 +75,7 @@ func (h *handler) updateCategory(w http.ResponseWriter, r *http.Request) {
 	response.JSONCreated(w, r, category)
 }
 
-func (h *handler) markCategoryAsRead(w http.ResponseWriter, r *http.Request) {
+func (h *handler) markCategoryAsReadHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 	categoryID := request.RouteInt64Param(r, "categoryID")
 
@@ -98,7 +98,7 @@ func (h *handler) markCategoryAsRead(w http.ResponseWriter, r *http.Request) {
 	response.JSONNoContent(w, r)
 }
 
-func (h *handler) getCategories(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getCategoriesHandler(w http.ResponseWriter, r *http.Request) {
 	var categories model.Categories
 	var err error
 	includeCounts := request.QueryStringParam(r, "counts", "false")
@@ -116,7 +116,7 @@ func (h *handler) getCategories(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, categories)
 }
 
-func (h *handler) removeCategory(w http.ResponseWriter, r *http.Request) {
+func (h *handler) removeCategoryHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 	categoryID := request.RouteInt64Param(r, "categoryID")
 
@@ -133,7 +133,7 @@ func (h *handler) removeCategory(w http.ResponseWriter, r *http.Request) {
 	response.JSONNoContent(w, r)
 }
 
-func (h *handler) refreshCategory(w http.ResponseWriter, r *http.Request) {
+func (h *handler) refreshCategoryHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 	categoryID := request.RouteInt64Param(r, "categoryID")
 

+ 2 - 2
internal/api/enclosure.go → internal/api/enclosure_handlers.go

@@ -14,7 +14,7 @@ import (
 	"miniflux.app/v2/internal/validator"
 )
 
-func (h *handler) getEnclosureByID(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getEnclosureByIDHandler(w http.ResponseWriter, r *http.Request) {
 	enclosureID := request.RouteInt64Param(r, "enclosureID")
 
 	enclosure, err := h.store.GetEnclosure(enclosureID)
@@ -39,7 +39,7 @@ func (h *handler) getEnclosureByID(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, enclosure)
 }
 
-func (h *handler) updateEnclosureByID(w http.ResponseWriter, r *http.Request) {
+func (h *handler) updateEnclosureByIDHandler(w http.ResponseWriter, r *http.Request) {
 	enclosureID := request.RouteInt64Param(r, "enclosureID")
 
 	var enclosureUpdateRequest model.EnclosureUpdateRequest

+ 13 - 13
internal/api/entry.go → internal/api/entry_handlers.go

@@ -42,7 +42,7 @@ func (h *handler) getEntryFromBuilder(w http.ResponseWriter, r *http.Request, b
 	response.JSON(w, r, entry)
 }
 
-func (h *handler) getFeedEntry(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getFeedEntryHandler(w http.ResponseWriter, r *http.Request) {
 	feedID := request.RouteInt64Param(r, "feedID")
 	entryID := request.RouteInt64Param(r, "entryID")
 
@@ -54,7 +54,7 @@ func (h *handler) getFeedEntry(w http.ResponseWriter, r *http.Request) {
 	h.getEntryFromBuilder(w, r, builder)
 }
 
-func (h *handler) getCategoryEntry(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getCategoryEntryHandler(w http.ResponseWriter, r *http.Request) {
 	categoryID := request.RouteInt64Param(r, "categoryID")
 	entryID := request.RouteInt64Param(r, "entryID")
 
@@ -66,7 +66,7 @@ func (h *handler) getCategoryEntry(w http.ResponseWriter, r *http.Request) {
 	h.getEntryFromBuilder(w, r, builder)
 }
 
-func (h *handler) getEntry(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getEntryHandler(w http.ResponseWriter, r *http.Request) {
 	entryID := request.RouteInt64Param(r, "entryID")
 	builder := h.store.NewEntryQueryBuilder(request.UserID(r))
 	builder.WithEntryID(entryID)
@@ -75,17 +75,17 @@ func (h *handler) getEntry(w http.ResponseWriter, r *http.Request) {
 	h.getEntryFromBuilder(w, r, builder)
 }
 
-func (h *handler) getFeedEntries(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getFeedEntriesHandler(w http.ResponseWriter, r *http.Request) {
 	feedID := request.RouteInt64Param(r, "feedID")
 	h.findEntries(w, r, feedID, 0)
 }
 
-func (h *handler) getCategoryEntries(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getCategoryEntriesHandler(w http.ResponseWriter, r *http.Request) {
 	categoryID := request.RouteInt64Param(r, "categoryID")
 	h.findEntries(w, r, 0, categoryID)
 }
 
-func (h *handler) getEntries(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getEntriesHandler(w http.ResponseWriter, r *http.Request) {
 	h.findEntries(w, r, 0, 0)
 }
 
@@ -172,7 +172,7 @@ func (h *handler) findEntries(w http.ResponseWriter, r *http.Request, feedID int
 	response.JSON(w, r, &entriesResponse{Total: count, Entries: entries})
 }
 
-func (h *handler) setEntryStatus(w http.ResponseWriter, r *http.Request) {
+func (h *handler) setEntryStatusHandler(w http.ResponseWriter, r *http.Request) {
 	var entriesStatusUpdateRequest model.EntriesStatusUpdateRequest
 	if err := json_parser.NewDecoder(r.Body).Decode(&entriesStatusUpdateRequest); err != nil {
 		response.JSONBadRequest(w, r, err)
@@ -192,7 +192,7 @@ func (h *handler) setEntryStatus(w http.ResponseWriter, r *http.Request) {
 	response.JSONNoContent(w, r)
 }
 
-func (h *handler) toggleStarred(w http.ResponseWriter, r *http.Request) {
+func (h *handler) toggleStarredHandler(w http.ResponseWriter, r *http.Request) {
 	entryID := request.RouteInt64Param(r, "entryID")
 	if err := h.store.ToggleStarred(request.UserID(r), entryID); err != nil {
 		response.JSONServerError(w, r, err)
@@ -202,7 +202,7 @@ func (h *handler) toggleStarred(w http.ResponseWriter, r *http.Request) {
 	response.JSONNoContent(w, r)
 }
 
-func (h *handler) saveEntry(w http.ResponseWriter, r *http.Request) {
+func (h *handler) saveEntryHandler(w http.ResponseWriter, r *http.Request) {
 	entryID := request.RouteInt64Param(r, "entryID")
 	builder := h.store.NewEntryQueryBuilder(request.UserID(r))
 	builder.WithEntryID(entryID)
@@ -235,7 +235,7 @@ func (h *handler) saveEntry(w http.ResponseWriter, r *http.Request) {
 	response.JSONAccepted(w, r)
 }
 
-func (h *handler) updateEntry(w http.ResponseWriter, r *http.Request) {
+func (h *handler) updateEntryHandler(w http.ResponseWriter, r *http.Request) {
 	var entryUpdateRequest model.EntryUpdateRequest
 	if err := json_parser.NewDecoder(r.Body).Decode(&entryUpdateRequest); err != nil {
 		response.JSONBadRequest(w, r, err)
@@ -294,7 +294,7 @@ func (h *handler) updateEntry(w http.ResponseWriter, r *http.Request) {
 	response.JSONCreated(w, r, entry)
 }
 
-func (h *handler) importFeedEntry(w http.ResponseWriter, r *http.Request) {
+func (h *handler) importFeedEntryHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 	feedID := request.RouteInt64Param(r, "feedID")
 
@@ -398,7 +398,7 @@ func (h *handler) importFeedEntry(w http.ResponseWriter, r *http.Request) {
 	}
 }
 
-func (h *handler) fetchContent(w http.ResponseWriter, r *http.Request) {
+func (h *handler) fetchContentHandler(w http.ResponseWriter, r *http.Request) {
 	loggedUserID := request.UserID(r)
 	entryID := request.RouteInt64Param(r, "entryID")
 
@@ -457,7 +457,7 @@ func (h *handler) fetchContent(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, entryContentResponse{Content: mediaproxy.RewriteDocumentWithAbsoluteProxyURL(entry.Content), ReadingTime: entry.ReadingTime})
 }
 
-func (h *handler) flushHistory(w http.ResponseWriter, r *http.Request) {
+func (h *handler) flushHistoryHandler(w http.ResponseWriter, r *http.Request) {
 	loggedUserID := request.UserID(r)
 	go h.store.FlushHistory(loggedUserID)
 	response.JSONAccepted(w, r)

+ 10 - 10
internal/api/feed.go → internal/api/feed_handlers.go

@@ -17,7 +17,7 @@ import (
 	"miniflux.app/v2/internal/validator"
 )
 
-func (h *handler) createFeed(w http.ResponseWriter, r *http.Request) {
+func (h *handler) createFeedHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 
 	var feedCreationRequest model.FeedCreationRequest
@@ -50,7 +50,7 @@ func (h *handler) createFeed(w http.ResponseWriter, r *http.Request) {
 	response.JSONCreated(w, r, &feedCreationResponse{FeedID: feed.ID})
 }
 
-func (h *handler) refreshFeed(w http.ResponseWriter, r *http.Request) {
+func (h *handler) refreshFeedHandler(w http.ResponseWriter, r *http.Request) {
 	feedID := request.RouteInt64Param(r, "feedID")
 	userID := request.UserID(r)
 
@@ -68,7 +68,7 @@ func (h *handler) refreshFeed(w http.ResponseWriter, r *http.Request) {
 	response.JSONNoContent(w, r)
 }
 
-func (h *handler) refreshAllFeeds(w http.ResponseWriter, r *http.Request) {
+func (h *handler) refreshAllFeedsHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 
 	batchBuilder := h.store.NewBatchBuilder()
@@ -95,7 +95,7 @@ func (h *handler) refreshAllFeeds(w http.ResponseWriter, r *http.Request) {
 	response.JSONNoContent(w, r)
 }
 
-func (h *handler) updateFeed(w http.ResponseWriter, r *http.Request) {
+func (h *handler) updateFeedHandler(w http.ResponseWriter, r *http.Request) {
 	var feedModificationRequest model.FeedModificationRequest
 	if err := json_parser.NewDecoder(r.Body).Decode(&feedModificationRequest); err != nil {
 		response.JSONBadRequest(w, r, err)
@@ -137,7 +137,7 @@ func (h *handler) updateFeed(w http.ResponseWriter, r *http.Request) {
 	response.JSONCreated(w, r, originalFeed)
 }
 
-func (h *handler) markFeedAsRead(w http.ResponseWriter, r *http.Request) {
+func (h *handler) markFeedAsReadHandler(w http.ResponseWriter, r *http.Request) {
 	feedID := request.RouteInt64Param(r, "feedID")
 	userID := request.UserID(r)
 
@@ -154,7 +154,7 @@ func (h *handler) markFeedAsRead(w http.ResponseWriter, r *http.Request) {
 	response.JSONNoContent(w, r)
 }
 
-func (h *handler) getCategoryFeeds(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getCategoryFeedsHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 	categoryID := request.RouteInt64Param(r, "categoryID")
 
@@ -178,7 +178,7 @@ func (h *handler) getCategoryFeeds(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, feeds)
 }
 
-func (h *handler) getFeeds(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getFeedsHandler(w http.ResponseWriter, r *http.Request) {
 	feeds, err := h.store.Feeds(request.UserID(r))
 	if err != nil {
 		response.JSONServerError(w, r, err)
@@ -188,7 +188,7 @@ func (h *handler) getFeeds(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, feeds)
 }
 
-func (h *handler) fetchCounters(w http.ResponseWriter, r *http.Request) {
+func (h *handler) fetchCountersHandler(w http.ResponseWriter, r *http.Request) {
 	counters, err := h.store.FetchCounters(request.UserID(r))
 	if err != nil {
 		response.JSONServerError(w, r, err)
@@ -198,7 +198,7 @@ func (h *handler) fetchCounters(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, counters)
 }
 
-func (h *handler) getFeed(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getFeedHandler(w http.ResponseWriter, r *http.Request) {
 	feedID := request.RouteInt64Param(r, "feedID")
 	feed, err := h.store.FeedByID(request.UserID(r), feedID)
 	if err != nil {
@@ -214,7 +214,7 @@ func (h *handler) getFeed(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, feed)
 }
 
-func (h *handler) removeFeed(w http.ResponseWriter, r *http.Request) {
+func (h *handler) removeFeedHandler(w http.ResponseWriter, r *http.Request) {
 	feedID := request.RouteInt64Param(r, "feedID")
 	userID := request.UserID(r)
 

+ 2 - 2
internal/api/icon.go → internal/api/icon_handlers.go

@@ -10,7 +10,7 @@ import (
 	"miniflux.app/v2/internal/http/response"
 )
 
-func (h *handler) getIconByFeedID(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getIconByFeedIDHandler(w http.ResponseWriter, r *http.Request) {
 	feedID := request.RouteInt64Param(r, "feedID")
 
 	icon, err := h.store.IconByFeedID(request.UserID(r), feedID)
@@ -31,7 +31,7 @@ func (h *handler) getIconByFeedID(w http.ResponseWriter, r *http.Request) {
 	})
 }
 
-func (h *handler) getIconByIconID(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getIconByIconIDHandler(w http.ResponseWriter, r *http.Request) {
 	iconID := request.RouteInt64Param(r, "iconID")
 
 	icon, err := h.store.IconByID(iconID)

+ 2 - 2
internal/api/opml.go → internal/api/opml_handlers.go

@@ -11,7 +11,7 @@ import (
 	"miniflux.app/v2/internal/reader/opml"
 )
 
-func (h *handler) exportFeeds(w http.ResponseWriter, r *http.Request) {
+func (h *handler) exportFeedsHandler(w http.ResponseWriter, r *http.Request) {
 	opmlHandler := opml.NewHandler(h.store)
 	opmlExport, err := opmlHandler.Export(request.UserID(r))
 	if err != nil {
@@ -22,7 +22,7 @@ func (h *handler) exportFeeds(w http.ResponseWriter, r *http.Request) {
 	response.XML(w, r, opmlExport)
 }
 
-func (h *handler) importFeeds(w http.ResponseWriter, r *http.Request) {
+func (h *handler) importFeedsHandler(w http.ResponseWriter, r *http.Request) {
 	opmlHandler := opml.NewHandler(h.store)
 	err := opmlHandler.Import(request.UserID(r), r.Body)
 	defer r.Body.Close()

+ 1 - 1
internal/api/subscription.go → internal/api/subscription_handlers.go

@@ -17,7 +17,7 @@ import (
 	"miniflux.app/v2/internal/validator"
 )
 
-func (h *handler) discoverSubscriptions(w http.ResponseWriter, r *http.Request) {
+func (h *handler) discoverSubscriptionsHandler(w http.ResponseWriter, r *http.Request) {
 	var subscriptionDiscoveryRequest model.SubscriptionDiscoveryRequest
 	if err := json_parser.NewDecoder(r.Body).Decode(&subscriptionDiscoveryRequest); err != nil {
 		response.JSONBadRequest(w, r, err)

+ 9 - 9
internal/api/user.go → internal/api/user_handlers.go

@@ -14,7 +14,7 @@ import (
 	"miniflux.app/v2/internal/validator"
 )
 
-func (h *handler) currentUser(w http.ResponseWriter, r *http.Request) {
+func (h *handler) currentUserHandler(w http.ResponseWriter, r *http.Request) {
 	user, err := h.store.UserByID(request.UserID(r))
 	if err != nil {
 		response.JSONServerError(w, r, err)
@@ -24,7 +24,7 @@ func (h *handler) currentUser(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, user)
 }
 
-func (h *handler) createUser(w http.ResponseWriter, r *http.Request) {
+func (h *handler) createUserHandler(w http.ResponseWriter, r *http.Request) {
 	if !request.IsAdminUser(r) {
 		response.JSONForbidden(w, r)
 		return
@@ -50,7 +50,7 @@ func (h *handler) createUser(w http.ResponseWriter, r *http.Request) {
 	response.JSONCreated(w, r, user)
 }
 
-func (h *handler) updateUser(w http.ResponseWriter, r *http.Request) {
+func (h *handler) updateUserHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.RouteInt64Param(r, "userID")
 
 	var userModificationRequest model.UserModificationRequest
@@ -96,7 +96,7 @@ func (h *handler) updateUser(w http.ResponseWriter, r *http.Request) {
 	response.JSONCreated(w, r, originalUser)
 }
 
-func (h *handler) markUserAsRead(w http.ResponseWriter, r *http.Request) {
+func (h *handler) markUserAsReadHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.RouteInt64Param(r, "userID")
 	if userID != request.UserID(r) {
 		response.JSONForbidden(w, r)
@@ -116,7 +116,7 @@ func (h *handler) markUserAsRead(w http.ResponseWriter, r *http.Request) {
 	response.JSONNoContent(w, r)
 }
 
-func (h *handler) getIntegrationsStatus(w http.ResponseWriter, r *http.Request) {
+func (h *handler) getIntegrationsStatusHandler(w http.ResponseWriter, r *http.Request) {
 	userID := request.UserID(r)
 
 	if _, err := h.store.UserByID(userID); err != nil {
@@ -129,7 +129,7 @@ func (h *handler) getIntegrationsStatus(w http.ResponseWriter, r *http.Request)
 	response.JSON(w, r, integrationsStatusResponse{HasIntegrations: hasIntegrations})
 }
 
-func (h *handler) users(w http.ResponseWriter, r *http.Request) {
+func (h *handler) usersHandler(w http.ResponseWriter, r *http.Request) {
 	if !request.IsAdminUser(r) {
 		response.JSONForbidden(w, r)
 		return
@@ -145,7 +145,7 @@ func (h *handler) users(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, users)
 }
 
-func (h *handler) userByID(w http.ResponseWriter, r *http.Request) {
+func (h *handler) userByIDHandler(w http.ResponseWriter, r *http.Request) {
 	if !request.IsAdminUser(r) {
 		response.JSONForbidden(w, r)
 		return
@@ -167,7 +167,7 @@ func (h *handler) userByID(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, user)
 }
 
-func (h *handler) userByUsername(w http.ResponseWriter, r *http.Request) {
+func (h *handler) userByUsernameHandler(w http.ResponseWriter, r *http.Request) {
 	if !request.IsAdminUser(r) {
 		response.JSONForbidden(w, r)
 		return
@@ -188,7 +188,7 @@ func (h *handler) userByUsername(w http.ResponseWriter, r *http.Request) {
 	response.JSON(w, r, user)
 }
 
-func (h *handler) removeUser(w http.ResponseWriter, r *http.Request) {
+func (h *handler) removeUserHandler(w http.ResponseWriter, r *http.Request) {
 	if !request.IsAdminUser(r) {
 		response.JSONForbidden(w, r)
 		return

+ 24 - 0
internal/api/version_handler.go

@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package api // import "miniflux.app/v2/internal/api"
+
+import (
+	"net/http"
+	"runtime"
+
+	"miniflux.app/v2/internal/http/response"
+	"miniflux.app/v2/internal/version"
+)
+
+func (h *handler) versionHandler(w http.ResponseWriter, r *http.Request) {
+	response.JSON(w, r, &versionResponse{
+		Version:   version.Version,
+		Commit:    version.Commit,
+		BuildDate: version.BuildDate,
+		GoVersion: runtime.Version(),
+		Compiler:  runtime.Compiler,
+		Arch:      runtime.GOARCH,
+		OS:        runtime.GOOS,
+	})
+}