From 35f2d399e2aac397b8fa7d5ad0eb0e4af1db0f40 Mon Sep 17 00:00:00 2001 From: boojack Date: Wed, 9 Aug 2023 22:30:27 +0800 Subject: [PATCH] chore: update api v1 docs (#2117) * chore: update apiv1 docs * chore: update --- api/v1/auth.go | 24 +-- api/{ => v1}/docs.go | 190 +++++++++--------- api/v1/http_getter.go | 24 +-- api/v1/idp.go | 31 ++- api/v1/memo.go | 43 ++-- api/v1/memo_organizer.go | 6 +- api/v1/memo_relation.go | 18 +- api/v1/memo_resource.go | 18 +- api/v1/resource.go | 30 +-- api/v1/rss.go | 12 +- api/v1/storage.go | 24 +-- api/{ => v1}/swagger.yaml | 133 ++++++------ api/v1/system.go | 30 +-- api/v1/system_setting.go | 12 +- api/v1/tag.go | 24 +-- api/v1/user.go | 42 ++-- api/v1/user_setting.go | 8 +- docs/api/auth.md | 107 ---------- docs/api/how-to.md | 44 ---- docs/api/memo-relation.md | 67 ------ docs/api/memo-resource.md | 65 ------ docs/api/memo.md | 136 ------------- docs/api/resource.md | 130 ------------ docs/api/tag.md | 84 -------- docs/api/user.md | 164 --------------- docs/documenting-the-api.md | 6 +- ...-documentation.cfg => gen-api-v1-docs.cfg} | 4 +- ...-documentation.ps1 => gen-api-v1-docs.ps1} | 8 +- ...pi-documentation.sh => gen-api-v1-docs.sh} | 10 +- server/server.go | 7 +- 30 files changed, 351 insertions(+), 1150 deletions(-) rename api/{ => v1}/docs.go (99%) rename api/{ => v1}/swagger.yaml (99%) delete mode 100644 docs/api/auth.md delete mode 100644 docs/api/how-to.md delete mode 100644 docs/api/memo-relation.md delete mode 100644 docs/api/memo-resource.md delete mode 100644 docs/api/memo.md delete mode 100644 docs/api/resource.md delete mode 100644 docs/api/tag.md delete mode 100644 docs/api/user.md rename scripts/{generate-api-documentation.cfg => gen-api-v1-docs.cfg} (74%) rename scripts/{generate-api-documentation.ps1 => gen-api-v1-docs.ps1} (87%) rename scripts/{generate-api-documentation.sh => gen-api-v1-docs.sh} (91%) diff --git a/api/v1/auth.go b/api/v1/auth.go index 8d97e3c0..16c62c31 100644 --- a/api/v1/auth.go +++ b/api/v1/auth.go @@ -32,13 +32,13 @@ type SignUp struct { } func (s *APIV1Service) registerAuthRoutes(g *echo.Group) { - g.POST("/auth/signin", s.signIn) - g.POST("/auth/signin/sso", s.signInSSO) - g.POST("/auth/signout", s.signOut) - g.POST("/auth/signup", s.signUp) + g.POST("/auth/signin", s.SignIn) + g.POST("/auth/signin/sso", s.SignInSSO) + g.POST("/auth/signout", s.SignOut) + g.POST("/auth/signup", s.SignUp) } -// signIn godoc +// SignIn godoc // // @Summary Sign-in to memos. // @Tags auth @@ -51,7 +51,7 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group) { // @Failure 403 {object} nil "User has been archived with username %s" // @Failure 500 {object} nil "Failed to find system setting | Failed to unmarshal system setting | Incorrect login credentials, please try again | Failed to generate tokens | Failed to create activity" // @Router /api/v1/auth/signin [POST] -func (s *APIV1Service) signIn(c echo.Context) error { +func (s *APIV1Service) SignIn(c echo.Context) error { ctx := c.Request().Context() signin := &SignIn{} @@ -104,7 +104,7 @@ func (s *APIV1Service) signIn(c echo.Context) error { return c.JSON(http.StatusOK, userMessage) } -// signInSSO godoc +// SignInSSO godoc // // @Summary Sign-in to memos using SSO. // @Tags auth @@ -118,7 +118,7 @@ func (s *APIV1Service) signIn(c echo.Context) error { // @Failure 404 {object} nil "Identity provider not found" // @Failure 500 {object} nil "Failed to find identity provider | Failed to create identity provider instance | Failed to exchange token | Failed to get user info | Failed to compile identifier filter | Incorrect login credentials, please try again | Failed to generate random password | Failed to generate password hash | Failed to create user | Failed to generate tokens | Failed to create activity" // @Router /api/v1/auth/signin/sso [POST] -func (s *APIV1Service) signInSSO(c echo.Context) error { +func (s *APIV1Service) SignInSSO(c echo.Context) error { ctx := c.Request().Context() signin := &SSOSignIn{} if err := json.NewDecoder(c.Request().Body).Decode(signin); err != nil { @@ -205,19 +205,19 @@ func (s *APIV1Service) signInSSO(c echo.Context) error { return c.JSON(http.StatusOK, userMessage) } -// signOut godoc +// SignOut godoc // // @Summary Sign-out from memos. // @Tags auth // @Produce json // @Success 200 {boolean} true "Sign-out success" // @Router /api/v1/auth/signout [POST] -func (*APIV1Service) signOut(c echo.Context) error { +func (*APIV1Service) SignOut(c echo.Context) error { RemoveTokensAndCookies(c) return c.JSON(http.StatusOK, true) } -// signUp godoc +// SignUp godoc // // @Summary Sign-up to memos. // @Tags auth @@ -231,7 +231,7 @@ func (*APIV1Service) signOut(c echo.Context) error { // @Failure 404 {object} nil "Not found" // @Failure 500 {object} nil "Failed to find system setting | Failed to unmarshal system setting allow signup | Failed to generate password hash | Failed to create user | Failed to generate tokens | Failed to create activity" // @Router /api/v1/auth/signup [POST] -func (s *APIV1Service) signUp(c echo.Context) error { +func (s *APIV1Service) SignUp(c echo.Context) error { ctx := c.Request().Context() signup := &SignUp{} if err := json.NewDecoder(c.Request().Body).Decode(signup); err != nil { diff --git a/api/docs.go b/api/v1/docs.go similarity index 99% rename from api/docs.go rename to api/v1/docs.go index 46237942..2bd74b78 100644 --- a/api/docs.go +++ b/api/v1/docs.go @@ -1,6 +1,6 @@ // Code generated by swaggo/swag. DO NOT EDIT. -package api +package v1 import "github.com/swaggo/swag" @@ -23,6 +23,50 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/api/v1/GetSystemStatus": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "system" + ], + "summary": "Get system GetSystemStatus", + "responses": { + "200": { + "description": "System GetSystemStatus", + "schema": { + "$ref": "#/definitions/v1.SystemStatus" + } + }, + "401": { + "description": "Missing user in session | Unauthorized" + }, + "500": { + "description": "Failed to find host user | Failed to find system setting list | Failed to unmarshal system setting customized profile value" + } + } + } + }, + "/api/v1/PingSystem": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "system" + ], + "summary": "Ping the system", + "responses": { + "200": { + "description": "System profile", + "schema": { + "$ref": "#/definitions/profile.Profile" + } + } + } + } + }, "/api/v1/auth/signin": { "post": { "consumes": [ @@ -1108,25 +1152,6 @@ const docTemplate = `{ } } }, - "/api/v1/ping": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "system" - ], - "summary": "Ping the system", - "responses": { - "200": { - "description": "System profile", - "schema": { - "$ref": "#/definitions/profile.Profile" - } - } - } - } - }, "/api/v1/resource": { "get": { "security": [ @@ -1361,31 +1386,6 @@ const docTemplate = `{ } } }, - "/api/v1/status": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "system" - ], - "summary": "Get system status", - "responses": { - "200": { - "description": "System status", - "schema": { - "$ref": "#/definitions/v1.SystemStatus" - } - }, - "401": { - "description": "Missing user in session | Unauthorized" - }, - "500": { - "description": "Failed to find host user | Failed to find system setting list | Failed to unmarshal system setting customized profile value" - } - } - } - }, "/api/v1/storage": { "get": { "security": [ @@ -1555,6 +1555,36 @@ const docTemplate = `{ } } }, + "/api/v1/system/ExecVacuum": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "system" + ], + "summary": "Vacuum the database", + "responses": { + "200": { + "description": "Database vacuumed", + "schema": { + "type": "boolean" + } + }, + "401": { + "description": "Missing user in session | Unauthorized" + }, + "500": { + "description": "Failed to find user | Failed to ExecVacuum database" + } + } + } + }, "/api/v1/system/setting": { "get": { "security": [ @@ -1636,36 +1666,6 @@ const docTemplate = `{ } } }, - "/api/v1/system/vacuum": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "system" - ], - "summary": "Vacuum the database", - "responses": { - "200": { - "description": "Database vacuumed", - "schema": { - "type": "boolean" - } - }, - "401": { - "description": "Missing user in session | Unauthorized" - }, - "500": { - "description": "Failed to find user | Failed to vacuum database" - } - } - } - }, "/api/v1/tag": { "get": { "security": [ @@ -1972,7 +1972,7 @@ const docTemplate = `{ "tags": [ "user-setting" ], - "summary": "Create user setting", + "summary": "Upsert user setting", "parameters": [ { "description": "Request object.", @@ -2144,19 +2144,19 @@ const docTemplate = `{ } } }, - "/o/get/httpmeta": { + "/o/get/GetImage": { "get": { "produces": [ - "application/json" + "GetImage/*" ], "tags": [ "get" ], - "summary": "Get website metadata", + "summary": "Get GetImage from URL", "parameters": [ { "type": "string", - "description": "Website URL", + "description": "Image url", "name": "url", "in": "query", "required": true @@ -2164,33 +2164,30 @@ const docTemplate = `{ ], "responses": { "200": { - "description": "Extracted metadata", - "schema": { - "$ref": "#/definitions/getter.HTMLMeta" - } + "description": "Image" }, "400": { - "description": "Missing website url | Wrong url" + "description": "Missing GetImage url | Wrong url | Failed to get GetImage url: %s" }, - "406": { - "description": "Failed to get website meta with url: %s" + "500": { + "description": "Failed to write GetImage blob" } } } }, - "/o/get/image": { + "/o/get/GetWebsiteMetadata": { "get": { "produces": [ - "image/*" + "application/json" ], "tags": [ "get" ], - "summary": "Get image from URL", + "summary": "Get website metadata", "parameters": [ { "type": "string", - "description": "Image url", + "description": "Website URL", "name": "url", "in": "query", "required": true @@ -2198,13 +2195,16 @@ const docTemplate = `{ ], "responses": { "200": { - "description": "Image" + "description": "Extracted metadata", + "schema": { + "$ref": "#/definitions/getter.HTMLMeta" + } }, "400": { - "description": "Missing image url | Wrong url | Failed to get image url: %s" + "description": "Missing website url | Wrong url" }, - "500": { - "description": "Failed to write image blob" + "406": { + "description": "Failed to get website meta with url: %s" } } } diff --git a/api/v1/http_getter.go b/api/v1/http_getter.go index e132fc4d..3eaef4a8 100644 --- a/api/v1/http_getter.go +++ b/api/v1/http_getter.go @@ -11,13 +11,13 @@ import ( func (*APIV1Service) registerGetterPublicRoutes(g *echo.Group) { // GET /get/httpmeta?url={url} - Get website meta. - g.GET("/get/httpmeta", httpmeta) + g.GET("/get/httpmeta", GetWebsiteMetadata) // GET /get/image?url={url} - Get image. - g.GET("/get/image", image) + g.GET("/get/image", GetImage) } -// httpmeta godoc +// GetWebsiteMetadata godoc // // @Summary Get website metadata // @Tags get @@ -26,8 +26,8 @@ func (*APIV1Service) registerGetterPublicRoutes(g *echo.Group) { // @Success 200 {object} getter.HTMLMeta "Extracted metadata" // @Failure 400 {object} nil "Missing website url | Wrong url" // @Failure 406 {object} nil "Failed to get website meta with url: %s" -// @Router /o/get/httpmeta [GET] -func httpmeta(c echo.Context) error { +// @Router /o/get/GetWebsiteMetadata [GET] +func GetWebsiteMetadata(c echo.Context) error { urlStr := c.QueryParam("url") if urlStr == "" { return echo.NewHTTPError(http.StatusBadRequest, "Missing website url") @@ -43,17 +43,17 @@ func httpmeta(c echo.Context) error { return c.JSON(http.StatusOK, htmlMeta) } -// image godoc +// GetImage godoc // -// @Summary Get image from URL +// @Summary Get GetImage from URL // @Tags get -// @Produce image/* +// @Produce GetImage/* // @Param url query string true "Image url" // @Success 200 {object} nil "Image" -// @Failure 400 {object} nil "Missing image url | Wrong url | Failed to get image url: %s" -// @Failure 500 {object} nil "Failed to write image blob" -// @Router /o/get/image [GET] -func image(c echo.Context) error { +// @Failure 400 {object} nil "Missing GetImage url | Wrong url | Failed to get GetImage url: %s" +// @Failure 500 {object} nil "Failed to write GetImage blob" +// @Router /o/get/GetImage [GET] +func GetImage(c echo.Context) error { urlStr := c.QueryParam("url") if urlStr == "" { return echo.NewHTTPError(http.StatusBadRequest, "Missing image url") diff --git a/api/v1/idp.go b/api/v1/idp.go index 65360339..4780f396 100644 --- a/api/v1/idp.go +++ b/api/v1/idp.go @@ -65,15 +65,14 @@ type UpdateIdentityProviderRequest struct { } func (s *APIV1Service) registerIdentityProviderRoutes(g *echo.Group) { - g.GET("/idp", s.getIdentityProviderList) - g.POST("/idp", s.createIdentityProvider) - - g.GET("/idp/:idpId", s.getIdentityProvider) - g.DELETE("/idp/:idpId", s.deleteIdentityProvider) - g.PATCH("/idp/:idpId", s.updateIdentityProvider) + g.GET("/idp", s.GetIdentityProviderList) + g.POST("/idp", s.CreateIdentityProvider) + g.GET("/idp/:idpId", s.GetIdentityProvider) + g.PATCH("/idp/:idpId", s.UpdateIdentityProvider) + g.DELETE("/idp/:idpId", s.DeleteIdentityProvider) } -// getIdentityProviderList godoc +// GetIdentityProviderList godoc // // @Summary Get a list of identity providers // @Description *clientSecret is only available for host user @@ -82,7 +81,7 @@ func (s *APIV1Service) registerIdentityProviderRoutes(g *echo.Group) { // @Success 200 {object} []IdentityProvider "List of available identity providers" // @Failure 500 {object} nil "Failed to find identity provider list | Failed to find user" // @Router /api/v1/idp [GET] -func (s *APIV1Service) getIdentityProviderList(c echo.Context) error { +func (s *APIV1Service) GetIdentityProviderList(c echo.Context) error { ctx := c.Request().Context() list, err := s.Store.ListIdentityProviders(ctx, &store.FindIdentityProvider{}) if err != nil { @@ -115,7 +114,7 @@ func (s *APIV1Service) getIdentityProviderList(c echo.Context) error { return c.JSON(http.StatusOK, identityProviderList) } -// createIdentityProvider godoc +// CreateIdentityProvider godoc // // @Summary Create Identity Provider // @Tags idp @@ -128,7 +127,7 @@ func (s *APIV1Service) getIdentityProviderList(c echo.Context) error { // @Failure 500 {object} nil "Failed to find user | Failed to create identity provider" // @Security ApiKeyAuth // @Router /api/v1/idp [POST] -func (s *APIV1Service) createIdentityProvider(c echo.Context) error { +func (s *APIV1Service) CreateIdentityProvider(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -162,7 +161,7 @@ func (s *APIV1Service) createIdentityProvider(c echo.Context) error { return c.JSON(http.StatusOK, convertIdentityProviderFromStore(identityProvider)) } -// getIdentityProvider godoc +// GetIdentityProvider godoc // // @Summary Get an identity provider by ID // @Tags idp @@ -176,7 +175,7 @@ func (s *APIV1Service) createIdentityProvider(c echo.Context) error { // @Failure 500 {object} nil "Failed to find identity provider list | Failed to find user" // @Security ApiKeyAuth // @Router /api/v1/idp/{idpId} [GET] -func (s *APIV1Service) getIdentityProvider(c echo.Context) error { +func (s *APIV1Service) GetIdentityProvider(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -210,7 +209,7 @@ func (s *APIV1Service) getIdentityProvider(c echo.Context) error { return c.JSON(http.StatusOK, convertIdentityProviderFromStore(identityProvider)) } -// deleteIdentityProvider godoc +// DeleteIdentityProvider godoc // // @Summary Delete an identity provider by ID // @Tags idp @@ -223,7 +222,7 @@ func (s *APIV1Service) getIdentityProvider(c echo.Context) error { // @Failure 500 {object} nil "Failed to find user | Failed to patch identity provider" // @Security ApiKeyAuth // @Router /api/v1/idp/{idpId} [DELETE] -func (s *APIV1Service) deleteIdentityProvider(c echo.Context) error { +func (s *APIV1Service) DeleteIdentityProvider(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -251,7 +250,7 @@ func (s *APIV1Service) deleteIdentityProvider(c echo.Context) error { return c.JSON(http.StatusOK, true) } -// updateIdentityProvider godoc +// UpdateIdentityProvider godoc // // @Summary Update an identity provider by ID // @Tags idp @@ -265,7 +264,7 @@ func (s *APIV1Service) deleteIdentityProvider(c echo.Context) error { // @Failure 500 {object} nil "Failed to find user | Failed to patch identity provider" // @Security ApiKeyAuth // @Router /api/v1/idp/{idpId} [PATCH] -func (s *APIV1Service) updateIdentityProvider(c echo.Context) error { +func (s *APIV1Service) UpdateIdentityProvider(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/api/v1/memo.go b/api/v1/memo.go index c8247c89..da7b7236 100644 --- a/api/v1/memo.go +++ b/api/v1/memo.go @@ -113,17 +113,16 @@ type FindMemoRequest struct { const maxContentLength = 1 << 30 func (s *APIV1Service) registerMemoRoutes(g *echo.Group) { - g.GET("/memo", s.getMemoList) - g.POST("/memo", s.createMemo) - g.GET("/memo/all", s.getAllMemos) - g.GET("/memo/stats", s.getMemoStats) - - g.GET("/memo/:memoId", s.getMemo) - g.DELETE("/memo/:memoId", s.deleteMemo) - g.PATCH("/memo/:memoId", s.updateMemo) + g.GET("/memo", s.GetMemoList) + g.POST("/memo", s.CreateMemo) + g.GET("/memo/all", s.GetAllMemos) + g.GET("/memo/stats", s.GetMemoStats) + g.GET("/memo/:memoId", s.GetMemo) + g.PATCH("/memo/:memoId", s.UpdateMemo) + g.DELETE("/memo/:memoId", s.DeleteMemo) } -// getMemoList godoc +// GetMemoList godoc // // @Summary Get a list of memos matching optional filters // @Tags memo @@ -141,7 +140,7 @@ func (s *APIV1Service) registerMemoRoutes(g *echo.Group) { // @Failure 500 {object} nil "Failed to get memo display with updated ts setting value | Failed to fetch memo list | Failed to compose memo response" // @Security ApiKeyAuth // @Router /api/v1/memo [GET] -func (s *APIV1Service) getMemoList(c echo.Context) error { +func (s *APIV1Service) GetMemoList(c echo.Context) error { ctx := c.Request().Context() findMemoMessage := &store.FindMemo{} if userID, err := util.ConvertStringToInt32(c.QueryParam("creatorId")); err == nil { @@ -225,7 +224,7 @@ func (s *APIV1Service) getMemoList(c echo.Context) error { return c.JSON(http.StatusOK, memoResponseList) } -// createMemo godoc +// CreateMemo godoc // // @Summary Create a memo // @Description Visibility can be PUBLIC, PROTECTED or PRIVATE @@ -244,7 +243,7 @@ func (s *APIV1Service) getMemoList(c echo.Context) error { // // NOTES: // - It's currently possible to create phantom resources and relations. Phantom relations will trigger backend 404's when fetching memo. -func (s *APIV1Service) createMemo(c echo.Context) error { +func (s *APIV1Service) CreateMemo(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -355,7 +354,7 @@ func (s *APIV1Service) createMemo(c echo.Context) error { return c.JSON(http.StatusOK, memoResponse) } -// getAllMemos godoc +// GetAllMemos godoc // // @Summary Get a list of public memos matching optional filters // @Description This should also list protected memos if the user is logged in @@ -371,7 +370,7 @@ func (s *APIV1Service) createMemo(c echo.Context) error { // // NOTES: // - creatorUsername is listed at ./web/src/helpers/api.ts:82, but it's not present here -func (s *APIV1Service) getAllMemos(c echo.Context) error { +func (s *APIV1Service) GetAllMemos(c echo.Context) error { ctx := c.Request().Context() findMemoMessage := &store.FindMemo{} _, ok := c.Get(auth.UserIDContextKey).(int32) @@ -415,7 +414,7 @@ func (s *APIV1Service) getAllMemos(c echo.Context) error { return c.JSON(http.StatusOK, memoResponseList) } -// getMemoStats godoc +// GetMemoStats godoc // // @Summary Get memo stats by creator ID or username // @Description Used to generate the heatmap @@ -427,7 +426,7 @@ func (s *APIV1Service) getAllMemos(c echo.Context) error { // @Failure 400 {object} nil "Missing user id to find memo" // @Failure 500 {object} nil "Failed to get memo display with updated ts setting value | Failed to find memo list | Failed to compose memo response" // @Router /api/v1/memo/stats [GET] -func (s *APIV1Service) getMemoStats(c echo.Context) error { +func (s *APIV1Service) GetMemoStats(c echo.Context) error { ctx := c.Request().Context() normalStatus := store.Normal findMemoMessage := &store.FindMemo{ @@ -487,7 +486,7 @@ func (s *APIV1Service) getMemoStats(c echo.Context) error { return c.JSON(http.StatusOK, displayTsList) } -// getMemo godoc +// GetMemo godoc // // @Summary Get memo by ID // @Tags memo @@ -500,7 +499,7 @@ func (s *APIV1Service) getMemoStats(c echo.Context) error { // @Failure 404 {object} nil "Memo not found: %d" // @Failure 500 {object} nil "Failed to find memo by ID: %v | Failed to compose memo response" // @Router /api/v1/memo/{memoId} [GET] -func (s *APIV1Service) getMemo(c echo.Context) error { +func (s *APIV1Service) GetMemo(c echo.Context) error { ctx := c.Request().Context() memoID, err := util.ConvertStringToInt32(c.Param("memoId")) if err != nil { @@ -534,7 +533,7 @@ func (s *APIV1Service) getMemo(c echo.Context) error { return c.JSON(http.StatusOK, memoResponse) } -// deleteMemo godoc +// DeleteMemo godoc // // @Summary Delete memo by ID // @Tags memo @@ -547,7 +546,7 @@ func (s *APIV1Service) getMemo(c echo.Context) error { // @Failure 500 {object} nil "Failed to find memo | Failed to delete memo ID: %v" // @Security ApiKeyAuth // @Router /api/v1/memo/{memoId} [DELETE] -func (s *APIV1Service) deleteMemo(c echo.Context) error { +func (s *APIV1Service) DeleteMemo(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -579,7 +578,7 @@ func (s *APIV1Service) deleteMemo(c echo.Context) error { return c.JSON(http.StatusOK, true) } -// updateMemo godoc +// UpdateMemo godoc // // @Summary Update a memo // @Description Visibility can be PUBLIC, PROTECTED or PRIVATE @@ -600,7 +599,7 @@ func (s *APIV1Service) deleteMemo(c echo.Context) error { // NOTES: // - It's currently possible to create phantom resources and relations. Phantom relations will trigger backend 404's when fetching memo. // - Passing 0 to createdTs and updatedTs will set them to 0 in the database, which is probably unwanted. -func (s *APIV1Service) updateMemo(c echo.Context) error { +func (s *APIV1Service) UpdateMemo(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/api/v1/memo_organizer.go b/api/v1/memo_organizer.go index b78b8f95..7d872061 100644 --- a/api/v1/memo_organizer.go +++ b/api/v1/memo_organizer.go @@ -22,10 +22,10 @@ type UpsertMemoOrganizerRequest struct { } func (s *APIV1Service) registerMemoOrganizerRoutes(g *echo.Group) { - g.POST("/memo/:memoId/organizer", s.organizeMemo) + g.POST("/memo/:memoId/organizer", s.CreateMemoOrganizer) } -// organizeMemo godoc +// CreateMemoOrganizer godoc // // @Summary Organize memo (pin/unpin) // @Tags memo-organizer @@ -40,7 +40,7 @@ func (s *APIV1Service) registerMemoOrganizerRoutes(g *echo.Group) { // @Failure 500 {object} nil "Failed to find memo | Failed to upsert memo organizer | Failed to find memo by ID: %v | Failed to compose memo response" // @Security ApiKeyAuth // @Router /api/v1/memo/{memoId}/organizer [POST] -func (s *APIV1Service) organizeMemo(c echo.Context) error { +func (s *APIV1Service) CreateMemoOrganizer(c echo.Context) error { ctx := c.Request().Context() memoID, err := util.ConvertStringToInt32(c.Param("memoId")) if err != nil { diff --git a/api/v1/memo_relation.go b/api/v1/memo_relation.go index 0c80821b..b67ce0b5 100644 --- a/api/v1/memo_relation.go +++ b/api/v1/memo_relation.go @@ -29,12 +29,12 @@ type UpsertMemoRelationRequest struct { } func (s *APIV1Service) registerMemoRelationRoutes(g *echo.Group) { - g.GET("/memo/:memoId/relation", s.getMemoRelationList) - g.POST("/memo/:memoId/relation", s.createMemoRelation) - g.DELETE("/memo/:memoId/relation/:relatedMemoId/type/:relationType", s.deleteMemoRelation) + g.GET("/memo/:memoId/relation", s.GetMemoRelationList) + g.POST("/memo/:memoId/relation", s.CreateMemoRelation) + g.DELETE("/memo/:memoId/relation/:relatedMemoId/type/:relationType", s.DeleteMemoRelation) } -// getMemoRelationList godoc +// GetMemoRelationList godoc // // @Summary Get a list of Memo Relations // @Tags memo-relation @@ -45,7 +45,7 @@ func (s *APIV1Service) registerMemoRelationRoutes(g *echo.Group) { // @Failure 400 {object} nil "ID is not a number: %s" // @Failure 500 {object} nil "Failed to list memo relations" // @Router /api/v1/memo/{memoId}/relation [GET] -func (s *APIV1Service) getMemoRelationList(c echo.Context) error { +func (s *APIV1Service) GetMemoRelationList(c echo.Context) error { ctx := c.Request().Context() memoID, err := util.ConvertStringToInt32(c.Param("memoId")) if err != nil { @@ -61,7 +61,7 @@ func (s *APIV1Service) getMemoRelationList(c echo.Context) error { return c.JSON(http.StatusOK, memoRelationList) } -// createMemoRelation godoc +// CreateMemoRelation godoc // // @Summary Create Memo Relation // @Description Create a relation between two memos @@ -79,7 +79,7 @@ func (s *APIV1Service) getMemoRelationList(c echo.Context) error { // - Currently not secured // - It's possible to create relations to memos that doesn't exist, which will trigger 404 errors when the frontend tries to load them. // - It's possible to create multiple relations, though the interface only shows first. -func (s *APIV1Service) createMemoRelation(c echo.Context) error { +func (s *APIV1Service) CreateMemoRelation(c echo.Context) error { ctx := c.Request().Context() memoID, err := util.ConvertStringToInt32(c.Param("memoId")) if err != nil { @@ -102,7 +102,7 @@ func (s *APIV1Service) createMemoRelation(c echo.Context) error { return c.JSON(http.StatusOK, memoRelation) } -// deleteMemoRelation godoc +// DeleteMemoRelation godoc // // @Summary Delete a Memo Relation // @Description Removes a relation between two memos @@ -120,7 +120,7 @@ func (s *APIV1Service) createMemoRelation(c echo.Context) error { // NOTES: // - Currently not secured. // - Will always return true, even if the relation doesn't exist. -func (s *APIV1Service) deleteMemoRelation(c echo.Context) error { +func (s *APIV1Service) DeleteMemoRelation(c echo.Context) error { ctx := c.Request().Context() memoID, err := util.ConvertStringToInt32(c.Param("memoId")) if err != nil { diff --git a/api/v1/memo_resource.go b/api/v1/memo_resource.go index 08cbe00d..f052e5dc 100644 --- a/api/v1/memo_resource.go +++ b/api/v1/memo_resource.go @@ -35,12 +35,12 @@ type MemoResourceDelete struct { } func (s *APIV1Service) registerMemoResourceRoutes(g *echo.Group) { - g.GET("/memo/:memoId/resource", s.getMemoResourceList) - g.POST("/memo/:memoId/resource", s.bindMemoResource) - g.DELETE("/memo/:memoId/resource/:resourceId", s.unbindMemoResource) + g.GET("/memo/:memoId/resource", s.GetMemoResourceList) + g.POST("/memo/:memoId/resource", s.BindMemoResource) + g.DELETE("/memo/:memoId/resource/:resourceId", s.UnbindMemoResource) } -// getMemoResourceList godoc +// GetMemoResourceList godoc // // @Summary Get resource list of a memo // @Tags memo-resource @@ -51,7 +51,7 @@ func (s *APIV1Service) registerMemoResourceRoutes(g *echo.Group) { // @Failure 400 {object} nil "ID is not a number: %s" // @Failure 500 {object} nil "Failed to fetch resource list" // @Router /api/v1/memo/{memoId}/resource [GET] -func (s *APIV1Service) getMemoResourceList(c echo.Context) error { +func (s *APIV1Service) GetMemoResourceList(c echo.Context) error { ctx := c.Request().Context() memoID, err := util.ConvertStringToInt32(c.Param("memoId")) if err != nil { @@ -71,7 +71,7 @@ func (s *APIV1Service) getMemoResourceList(c echo.Context) error { return c.JSON(http.StatusOK, resourceList) } -// bindMemoResource godoc +// BindMemoResource godoc // // @Summary Bind resource to memo // @Tags memo-resource @@ -88,7 +88,7 @@ func (s *APIV1Service) getMemoResourceList(c echo.Context) error { // // NOTES: // - Passing 0 to updatedTs will set it to 0 in the database, which is probably unwanted. -func (s *APIV1Service) bindMemoResource(c echo.Context) error { +func (s *APIV1Service) BindMemoResource(c echo.Context) error { ctx := c.Request().Context() memoID, err := util.ConvertStringToInt32(c.Param("memoId")) if err != nil { @@ -129,7 +129,7 @@ func (s *APIV1Service) bindMemoResource(c echo.Context) error { return c.JSON(http.StatusOK, true) } -// unbindMemoResource godoc +// UnbindMemoResource godoc // // @Summary Unbind resource from memo // @Tags memo-resource @@ -143,7 +143,7 @@ func (s *APIV1Service) bindMemoResource(c echo.Context) error { // @Failure 500 {object} nil "Failed to find memo | Failed to fetch resource list" // @Security ApiKeyAuth // @Router /api/v1/memo/{memoId}/resource/{resourceId} [DELETE] -func (s *APIV1Service) unbindMemoResource(c echo.Context) error { +func (s *APIV1Service) UnbindMemoResource(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/api/v1/resource.go b/api/v1/resource.go index c7c94d1b..ff71d640 100644 --- a/api/v1/resource.go +++ b/api/v1/resource.go @@ -81,11 +81,11 @@ const ( var fileKeyPattern = regexp.MustCompile(`\{[a-z]{1,9}\}`) func (s *APIV1Service) registerResourceRoutes(g *echo.Group) { - g.GET("/resource", s.getResourceList) - g.POST("/resource", s.createResource) - g.POST("/resource/blob", s.uploadResource) - g.DELETE("/resource/:resourceId", s.deleteResource) - g.PATCH("/resource/:resourceId", s.updateResource) + g.GET("/resource", s.GetResourceList) + g.POST("/resource", s.CreateResource) + g.POST("/resource/blob", s.UploadResource) + g.PATCH("/resource/:resourceId", s.UpdateResource) + g.DELETE("/resource/:resourceId", s.DeleteResource) } func (s *APIV1Service) registerResourcePublicRoutes(g *echo.Group) { @@ -93,7 +93,7 @@ func (s *APIV1Service) registerResourcePublicRoutes(g *echo.Group) { g.GET("/r/:resourceId/*", s.streamResource) } -// getResourceList godoc +// GetResourceList godoc // // @Summary Get a list of resources // @Tags resource @@ -105,7 +105,7 @@ func (s *APIV1Service) registerResourcePublicRoutes(g *echo.Group) { // @Failure 500 {object} nil "Failed to fetch resource list" // @Security ApiKeyAuth // @Router /api/v1/resource [GET] -func (s *APIV1Service) getResourceList(c echo.Context) error { +func (s *APIV1Service) GetResourceList(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -132,7 +132,7 @@ func (s *APIV1Service) getResourceList(c echo.Context) error { return c.JSON(http.StatusOK, resourceMessageList) } -// createResource godoc +// CreateResource godoc // // @Summary Create resource // @Tags resource @@ -145,7 +145,7 @@ func (s *APIV1Service) getResourceList(c echo.Context) error { // @Failure 500 {object} nil "Failed to save resource | Failed to create resource | Failed to create activity" // @Security ApiKeyAuth // @Router /api/v1/resource [POST] -func (s *APIV1Service) createResource(c echo.Context) error { +func (s *APIV1Service) CreateResource(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -219,7 +219,7 @@ func (s *APIV1Service) createResource(c echo.Context) error { return c.JSON(http.StatusOK, convertResourceFromStore(resource)) } -// uploadResource godoc +// UploadResource godoc // // @Summary Upload resource // @Tags resource @@ -232,7 +232,7 @@ func (s *APIV1Service) createResource(c echo.Context) error { // @Failure 500 {object} nil "Failed to get uploading file | Failed to open file | Failed to save resource | Failed to create resource | Failed to create activity" // @Security ApiKeyAuth // @Router /api/v1/resource/blob [POST] -func (s *APIV1Service) uploadResource(c echo.Context) error { +func (s *APIV1Service) UploadResource(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -292,7 +292,7 @@ func (s *APIV1Service) uploadResource(c echo.Context) error { return c.JSON(http.StatusOK, convertResourceFromStore(resource)) } -// deleteResource godoc +// DeleteResource godoc // // @Summary Delete a resource // @Tags resource @@ -305,7 +305,7 @@ func (s *APIV1Service) uploadResource(c echo.Context) error { // @Failure 500 {object} nil "Failed to find resource | Failed to delete resource" // @Security ApiKeyAuth // @Router /api/v1/resource/{resourceId} [DELETE] -func (s *APIV1Service) deleteResource(c echo.Context) error { +func (s *APIV1Service) DeleteResource(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -348,7 +348,7 @@ func (s *APIV1Service) deleteResource(c echo.Context) error { return c.JSON(http.StatusOK, true) } -// updateResource godoc +// UpdateResource godoc // // @Summary Update a resource // @Tags resource @@ -362,7 +362,7 @@ func (s *APIV1Service) deleteResource(c echo.Context) error { // @Failure 500 {object} nil "Failed to find resource | Failed to patch resource" // @Security ApiKeyAuth // @Router /api/v1/resource/{resourceId} [PATCH] -func (s *APIV1Service) updateResource(c echo.Context) error { +func (s *APIV1Service) UpdateResource(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/api/v1/rss.go b/api/v1/rss.go index 9d8ed0b5..f525e22b 100644 --- a/api/v1/rss.go +++ b/api/v1/rss.go @@ -21,11 +21,11 @@ const maxRSSItemCount = 100 const maxRSSItemTitleLength = 100 func (s *APIV1Service) registerRSSRoutes(g *echo.Group) { - g.GET("/explore/rss.xml", s.getRSS) - g.GET("/u/:id/rss.xml", s.getUserRSS) + g.GET("/explore/rss.xml", s.GetExploreRSS) + g.GET("/u/:id/rss.xml", s.GetUserRSS) } -// getRSS godoc +// GetExploreRSS godoc // // @Summary Get RSS // @Tags rss @@ -33,7 +33,7 @@ func (s *APIV1Service) registerRSSRoutes(g *echo.Group) { // @Success 200 {object} nil "RSS" // @Failure 500 {object} nil "Failed to get system customized profile | Failed to find memo list | Failed to generate rss" // @Router /explore/rss.xml [GET] -func (s *APIV1Service) getRSS(c echo.Context) error { +func (s *APIV1Service) GetExploreRSS(c echo.Context) error { ctx := c.Request().Context() systemCustomizedProfile, err := s.getSystemCustomizedProfile(ctx) if err != nil { @@ -59,7 +59,7 @@ func (s *APIV1Service) getRSS(c echo.Context) error { return c.String(http.StatusOK, rss) } -// getUserRSS godoc +// GetUserRSS godoc // // @Summary Get RSS for a user // @Tags rss @@ -69,7 +69,7 @@ func (s *APIV1Service) getRSS(c echo.Context) error { // @Failure 400 {object} nil "User id is not a number" // @Failure 500 {object} nil "Failed to get system customized profile | Failed to find memo list | Failed to generate rss" // @Router /u/{id}/rss.xml [GET] -func (s *APIV1Service) getUserRSS(c echo.Context) error { +func (s *APIV1Service) GetUserRSS(c echo.Context) error { ctx := c.Request().Context() id, err := util.ConvertStringToInt32(c.Param("id")) if err != nil { diff --git a/api/v1/storage.go b/api/v1/storage.go index add5a81a..c49df677 100644 --- a/api/v1/storage.go +++ b/api/v1/storage.go @@ -63,13 +63,13 @@ type UpdateStorageRequest struct { } func (s *APIV1Service) registerStorageRoutes(g *echo.Group) { - g.GET("/storage", s.getStorageList) - g.POST("/storage", s.createStorage) - g.DELETE("/storage/:storageId", s.deleteStorage) - g.PATCH("/storage/:storageId", s.updateStorage) + g.GET("/storage", s.GetStorageList) + g.POST("/storage", s.CreateStorage) + g.PATCH("/storage/:storageId", s.UpdateStorage) + g.DELETE("/storage/:storageId", s.DeleteStorage) } -// getStorageList godoc +// GetStorageList godoc // // @Summary Get a list of storages // @Tags storage @@ -79,7 +79,7 @@ func (s *APIV1Service) registerStorageRoutes(g *echo.Group) { // @Failure 500 {object} nil "Failed to find user | Failed to convert storage" // @Security ApiKeyAuth // @Router /api/v1/storage [GET] -func (s *APIV1Service) getStorageList(c echo.Context) error { +func (s *APIV1Service) GetStorageList(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -113,7 +113,7 @@ func (s *APIV1Service) getStorageList(c echo.Context) error { return c.JSON(http.StatusOK, storageList) } -// createStorage godoc +// CreateStorage godoc // // @Summary Create storage // @Tags storage @@ -126,7 +126,7 @@ func (s *APIV1Service) getStorageList(c echo.Context) error { // @Failure 500 {object} nil "Failed to find user | Failed to create storage | Failed to convert storage" // @Security ApiKeyAuth // @Router /api/v1/storage [POST] -func (s *APIV1Service) createStorage(c echo.Context) error { +func (s *APIV1Service) CreateStorage(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -172,7 +172,7 @@ func (s *APIV1Service) createStorage(c echo.Context) error { return c.JSON(http.StatusOK, storageMessage) } -// deleteStorage godoc +// DeleteStorage godoc // // @Summary Delete a storage // @Tags storage @@ -187,7 +187,7 @@ func (s *APIV1Service) createStorage(c echo.Context) error { // // NOTES: // - error message "Storage service %d is using" probably should be "Storage service %d is in use". -func (s *APIV1Service) deleteStorage(c echo.Context) error { +func (s *APIV1Service) DeleteStorage(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -230,7 +230,7 @@ func (s *APIV1Service) deleteStorage(c echo.Context) error { return c.JSON(http.StatusOK, true) } -// updateStorage godoc +// UpdateStorage godoc // // @Summary Update a storage // @Tags storage @@ -243,7 +243,7 @@ func (s *APIV1Service) deleteStorage(c echo.Context) error { // @Failure 500 {object} nil "Failed to find user | Failed to patch storage | Failed to convert storage" // @Security ApiKeyAuth // @Router /api/v1/storage/{storageId} [PATCH] -func (s *APIV1Service) updateStorage(c echo.Context) error { +func (s *APIV1Service) UpdateStorage(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/api/swagger.yaml b/api/v1/swagger.yaml similarity index 99% rename from api/swagger.yaml rename to api/v1/swagger.yaml index 8a438b1f..6933194a 100644 --- a/api/swagger.yaml +++ b/api/v1/swagger.yaml @@ -748,6 +748,35 @@ info: title: memos API version: "1.0" paths: + /api/v1/GetSystemStatus: + get: + produces: + - application/json + responses: + "200": + description: System GetSystemStatus + schema: + $ref: '#/definitions/v1.SystemStatus' + "401": + description: Missing user in session | Unauthorized + "500": + description: Failed to find host user | Failed to find system setting list + | Failed to unmarshal system setting customized profile value + summary: Get system GetSystemStatus + tags: + - system + /api/v1/PingSystem: + get: + produces: + - application/json + responses: + "200": + description: System profile + schema: + $ref: '#/definitions/profile.Profile' + summary: Ping the system + tags: + - system /api/v1/auth/signin: post: consumes: @@ -1480,18 +1509,6 @@ paths: summary: Get memo stats by creator ID or username tags: - memo - /api/v1/ping: - get: - produces: - - application/json - responses: - "200": - description: System profile - schema: - $ref: '#/definitions/profile.Profile' - summary: Ping the system - tags: - - system /api/v1/resource: get: parameters: @@ -1643,23 +1660,6 @@ paths: summary: Upload resource tags: - resource - /api/v1/status: - get: - produces: - - application/json - responses: - "200": - description: System status - schema: - $ref: '#/definitions/v1.SystemStatus' - "401": - description: Missing user in session | Unauthorized - "500": - description: Failed to find host user | Failed to find system setting list - | Failed to unmarshal system setting customized profile value - summary: Get system status - tags: - - system /api/v1/storage: get: produces: @@ -1769,6 +1769,24 @@ paths: summary: Update a storage tags: - storage + /api/v1/system/ExecVacuum: + post: + produces: + - application/json + responses: + "200": + description: Database vacuumed + schema: + type: boolean + "401": + description: Missing user in session | Unauthorized + "500": + description: Failed to find user | Failed to ExecVacuum database + security: + - ApiKeyAuth: [] + summary: Vacuum the database + tags: + - system /api/v1/system/setting: get: produces: @@ -1819,24 +1837,6 @@ paths: summary: Create system setting tags: - system-setting - /api/v1/system/vacuum: - post: - produces: - - application/json - responses: - "200": - description: Database vacuumed - schema: - type: boolean - "401": - description: Missing user in session | Unauthorized - "500": - description: Failed to find user | Failed to vacuum database - security: - - ApiKeyAuth: [] - summary: Vacuum the database - tags: - - system /api/v1/tag: get: produces: @@ -2129,7 +2129,7 @@ paths: description: Failed to upsert user setting security: - ApiKeyAuth: [] - summary: Create user setting + summary: Upsert user setting tags: - user-setting /explore/rss.xml: @@ -2145,46 +2145,47 @@ paths: summary: Get RSS tags: - rss - /o/get/httpmeta: + /o/get/GetImage: get: parameters: - - description: Website URL + - description: Image url in: query name: url required: true type: string produces: - - application/json + - GetImage/* responses: "200": - description: Extracted metadata - schema: - $ref: '#/definitions/getter.HTMLMeta' + description: Image "400": - description: Missing website url | Wrong url - "406": - description: 'Failed to get website meta with url: %s' - summary: Get website metadata + description: 'Missing GetImage url | Wrong url | Failed to get GetImage + url: %s' + "500": + description: Failed to write GetImage blob + summary: Get GetImage from URL tags: - get - /o/get/image: + /o/get/GetWebsiteMetadata: get: parameters: - - description: Image url + - description: Website URL in: query name: url required: true type: string produces: - - image/* + - application/json responses: "200": - description: Image + description: Extracted metadata + schema: + $ref: '#/definitions/getter.HTMLMeta' "400": - description: 'Missing image url | Wrong url | Failed to get image url: %s' - "500": - description: Failed to write image blob - summary: Get image from URL + description: Missing website url | Wrong url + "406": + description: 'Failed to get website meta with url: %s' + summary: Get website metadata tags: - get /o/r/{resourceId}: diff --git a/api/v1/system.go b/api/v1/system.go index 68a36e46..70a67f53 100644 --- a/api/v1/system.go +++ b/api/v1/system.go @@ -43,32 +43,32 @@ type SystemStatus struct { } func (s *APIV1Service) registerSystemRoutes(g *echo.Group) { - g.GET("/ping", s.ping) - g.GET("/status", s.status) - g.POST("/system/vacuum", s.vacuum) + g.GET("/ping", s.PingSystem) + g.GET("/status", s.GetSystemStatus) + g.POST("/system/vacuum", s.ExecVacuum) } -// ping godoc +// PingSystem godoc // // @Summary Ping the system // @Tags system // @Produce json // @Success 200 {object} profile.Profile "System profile" -// @Router /api/v1/ping [GET] -func (s *APIV1Service) ping(c echo.Context) error { +// @Router /api/v1/PingSystem [GET] +func (s *APIV1Service) PingSystem(c echo.Context) error { return c.JSON(http.StatusOK, s.Profile) } -// status godoc +// GetSystemStatus godoc // -// @Summary Get system status +// @Summary Get system GetSystemStatus // @Tags system // @Produce json -// @Success 200 {object} SystemStatus "System status" +// @Success 200 {object} SystemStatus "System GetSystemStatus" // @Failure 401 {object} nil "Missing user in session | Unauthorized" // @Failure 500 {object} nil "Failed to find host user | Failed to find system setting list | Failed to unmarshal system setting customized profile value" -// @Router /api/v1/status [GET] -func (s *APIV1Service) status(c echo.Context) error { +// @Router /api/v1/GetSystemStatus [GET] +func (s *APIV1Service) GetSystemStatus(c echo.Context) error { ctx := c.Request().Context() systemStatus := SystemStatus{ @@ -156,17 +156,17 @@ func (s *APIV1Service) status(c echo.Context) error { return c.JSON(http.StatusOK, systemStatus) } -// vacuum godoc +// ExecVacuum godoc // // @Summary Vacuum the database // @Tags system // @Produce json // @Success 200 {boolean} true "Database vacuumed" // @Failure 401 {object} nil "Missing user in session | Unauthorized" -// @Failure 500 {object} nil "Failed to find user | Failed to vacuum database" +// @Failure 500 {object} nil "Failed to find user | Failed to ExecVacuum database" // @Security ApiKeyAuth -// @Router /api/v1/system/vacuum [POST] -func (s *APIV1Service) vacuum(c echo.Context) error { +// @Router /api/v1/system/ExecVacuum [POST] +func (s *APIV1Service) ExecVacuum(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/api/v1/system_setting.go b/api/v1/system_setting.go index 3e1417b6..4d2c5dce 100644 --- a/api/v1/system_setting.go +++ b/api/v1/system_setting.go @@ -79,11 +79,11 @@ type UpsertSystemSettingRequest struct { } func (s *APIV1Service) registerSystemSettingRoutes(g *echo.Group) { - g.GET("/system/setting", s.getSystemSettingList) - g.POST("/system/setting", s.createSystemSetting) + g.GET("/system/setting", s.GetSystemSettingList) + g.POST("/system/setting", s.CreateSystemSetting) } -// getSystemSettingList godoc +// GetSystemSettingList godoc // // @Summary Get a list of system settings // @Tags system-setting @@ -93,7 +93,7 @@ func (s *APIV1Service) registerSystemSettingRoutes(g *echo.Group) { // @Failure 500 {object} nil "Failed to find user | Failed to find system setting list" // @Security ApiKeyAuth // @Router /api/v1/system/setting [GET] -func (s *APIV1Service) getSystemSettingList(c echo.Context) error { +func (s *APIV1Service) GetSystemSettingList(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -122,7 +122,7 @@ func (s *APIV1Service) getSystemSettingList(c echo.Context) error { return c.JSON(http.StatusOK, systemSettingList) } -// createSystemSetting godoc +// CreateSystemSetting godoc // // @Summary Create system setting // @Tags system-setting @@ -136,7 +136,7 @@ func (s *APIV1Service) getSystemSettingList(c echo.Context) error { // @Failure 500 {object} nil "Failed to find user | Failed to upsert system setting" // @Security ApiKeyAuth // @Router /api/v1/system/setting [POST] -func (s *APIV1Service) createSystemSetting(c echo.Context) error { +func (s *APIV1Service) CreateSystemSetting(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/api/v1/tag.go b/api/v1/tag.go index 10269da9..50e7d59f 100644 --- a/api/v1/tag.go +++ b/api/v1/tag.go @@ -28,13 +28,13 @@ type DeleteTagRequest struct { } func (s *APIV1Service) registerTagRoutes(g *echo.Group) { - g.GET("/tag", s.getTagList) - g.POST("/tag", s.createTag) - g.POST("/tag/delete", s.deleteTag) - g.GET("/tag/suggestion", s.getTagSuggestion) + g.GET("/tag", s.GetTagList) + g.POST("/tag", s.CreateTag) + g.GET("/tag/suggestion", s.GetTagSuggestion) + g.POST("/tag/delete", s.DeleteTag) } -// getTagList godoc +// GetTagList godoc // // @Summary Get a list of tags // @Tags tag @@ -44,7 +44,7 @@ func (s *APIV1Service) registerTagRoutes(g *echo.Group) { // @Failure 500 {object} nil "Failed to find tag list" // @Security ApiKeyAuth // @Router /api/v1/tag [GET] -func (s *APIV1Service) getTagList(c echo.Context) error { +func (s *APIV1Service) GetTagList(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -65,7 +65,7 @@ func (s *APIV1Service) getTagList(c echo.Context) error { return c.JSON(http.StatusOK, tagNameList) } -// createTag godoc +// CreateTag godoc // // @Summary Create a tag // @Tags tag @@ -78,7 +78,7 @@ func (s *APIV1Service) getTagList(c echo.Context) error { // @Failure 500 {object} nil "Failed to upsert tag | Failed to create activity" // @Security ApiKeyAuth // @Router /api/v1/tag [POST] -func (s *APIV1Service) createTag(c echo.Context) error { +func (s *APIV1Service) CreateTag(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -107,7 +107,7 @@ func (s *APIV1Service) createTag(c echo.Context) error { return c.JSON(http.StatusOK, tagMessage.Name) } -// deleteTag godoc +// DeleteTag godoc // // @Summary Delete a tag // @Tags tag @@ -120,7 +120,7 @@ func (s *APIV1Service) createTag(c echo.Context) error { // @Failure 500 {object} nil "Failed to delete tag name: %v" // @Security ApiKeyAuth // @Router /api/v1/tag/delete [POST] -func (s *APIV1Service) deleteTag(c echo.Context) error { +func (s *APIV1Service) DeleteTag(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -145,7 +145,7 @@ func (s *APIV1Service) deleteTag(c echo.Context) error { return c.JSON(http.StatusOK, true) } -// getTagSuggestion godoc +// GetTagSuggestion godoc // // @Summary Get a list of tags suggested from other memos contents // @Tags tag @@ -155,7 +155,7 @@ func (s *APIV1Service) deleteTag(c echo.Context) error { // @Failure 500 {object} nil "Failed to find memo list | Failed to find tag list" // @Security ApiKeyAuth // @Router /api/v1/tag/suggestion [GET] -func (s *APIV1Service) getTagSuggestion(c echo.Context) error { +func (s *APIV1Service) GetTagSuggestion(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/api/v1/user.go b/api/v1/user.go index e813d2ba..e2e192a4 100644 --- a/api/v1/user.go +++ b/api/v1/user.go @@ -68,17 +68,17 @@ type UpdateUserRequest struct { } func (s *APIV1Service) registerUserRoutes(g *echo.Group) { - g.GET("/user", s.getUserList) - g.POST("/user", s.createUser) - g.GET("/user/me", s.getCurrentUser) + g.GET("/user", s.GetUserList) + g.POST("/user", s.CreateUser) + g.GET("/user/me", s.GetCurrentUser) // NOTE: This should be moved to /api/v2/user/:username - g.GET("/user/name/:username", s.getUserByUsername) - g.GET("/user/:id", s.getUserByID) - g.DELETE("/user/:id", s.deleteUser) - g.PATCH("/user/:id", s.updateUser) + g.GET("/user/name/:username", s.GetUserByUsername) + g.GET("/user/:id", s.GetUserByID) + g.PATCH("/user/:id", s.UpdateUser) + g.DELETE("/user/:id", s.DeleteUser) } -// getUserList godoc +// GetUserList godoc // // @Summary Get a list of users // @Tags user @@ -86,7 +86,7 @@ func (s *APIV1Service) registerUserRoutes(g *echo.Group) { // @Success 200 {object} []store.User "User list" // @Failure 500 {object} nil "Failed to fetch user list" // @Router /api/v1/user [GET] -func (s *APIV1Service) getUserList(c echo.Context) error { +func (s *APIV1Service) GetUserList(c echo.Context) error { ctx := c.Request().Context() list, err := s.Store.ListUsers(ctx, &store.FindUser{}) if err != nil { @@ -104,7 +104,7 @@ func (s *APIV1Service) getUserList(c echo.Context) error { return c.JSON(http.StatusOK, userMessageList) } -// createUser godoc +// CreateUser godoc // // @Summary Create a user // @Tags user @@ -117,7 +117,7 @@ func (s *APIV1Service) getUserList(c echo.Context) error { // @Failure 403 {object} nil "Could not create host user" // @Failure 500 {object} nil "Failed to find user by id | Failed to generate password hash | Failed to create user | Failed to create activity" // @Router /api/v1/user [POST] -func (s *APIV1Service) createUser(c echo.Context) error { +func (s *APIV1Service) CreateUser(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -172,7 +172,7 @@ func (s *APIV1Service) createUser(c echo.Context) error { return c.JSON(http.StatusOK, userMessage) } -// getCurrentUser godoc +// GetCurrentUser godoc // // @Summary Get current user // @Tags user @@ -182,7 +182,7 @@ func (s *APIV1Service) createUser(c echo.Context) error { // @Failure 500 {object} nil "Failed to find user | Failed to find userSettingList" // @Security ApiKeyAuth // @Router /api/v1/user/me [GET] -func (s *APIV1Service) getCurrentUser(c echo.Context) error { +func (s *APIV1Service) GetCurrentUser(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -212,7 +212,7 @@ func (s *APIV1Service) getCurrentUser(c echo.Context) error { return c.JSON(http.StatusOK, userMessage) } -// getUserByUsername godoc +// GetUserByUsername godoc // // @Summary Get user by username // @Tags user @@ -222,7 +222,7 @@ func (s *APIV1Service) getCurrentUser(c echo.Context) error { // @Failure 404 {object} nil "User not found" // @Failure 500 {object} nil "Failed to find user" // @Router /api/v1/user/name/{username} [GET] -func (s *APIV1Service) getUserByUsername(c echo.Context) error { +func (s *APIV1Service) GetUserByUsername(c echo.Context) error { ctx := c.Request().Context() username := c.Param("username") user, err := s.Store.GetUser(ctx, &store.FindUser{Username: &username}) @@ -240,7 +240,7 @@ func (s *APIV1Service) getUserByUsername(c echo.Context) error { return c.JSON(http.StatusOK, userMessage) } -// getUserByID godoc +// GetUserByID godoc // // @Summary Get user by id // @Tags user @@ -251,7 +251,7 @@ func (s *APIV1Service) getUserByUsername(c echo.Context) error { // @Failure 404 {object} nil "User not found" // @Failure 500 {object} nil "Failed to find user" // @Router /api/v1/user/{id} [GET] -func (s *APIV1Service) getUserByID(c echo.Context) error { +func (s *APIV1Service) GetUserByID(c echo.Context) error { ctx := c.Request().Context() id, err := util.ConvertStringToInt32(c.Param("id")) if err != nil { @@ -273,7 +273,7 @@ func (s *APIV1Service) getUserByID(c echo.Context) error { return c.JSON(http.StatusOK, userMessage) } -// deleteUser godoc +// DeleteUser godoc // // @Summary Delete a user // @Tags user @@ -285,7 +285,7 @@ func (s *APIV1Service) getUserByID(c echo.Context) error { // @Failure 403 {object} nil "Unauthorized to delete user" // @Failure 500 {object} nil "Failed to find user | Failed to delete user" // @Router /api/v1/user/{id} [DELETE] -func (s *APIV1Service) deleteUser(c echo.Context) error { +func (s *APIV1Service) DeleteUser(c echo.Context) error { ctx := c.Request().Context() currentUserID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { @@ -317,7 +317,7 @@ func (s *APIV1Service) deleteUser(c echo.Context) error { return c.JSON(http.StatusOK, true) } -// updateUser godoc +// UpdateUser godoc // // @Summary Update a user // @Tags user @@ -330,7 +330,7 @@ func (s *APIV1Service) deleteUser(c echo.Context) error { // @Failure 403 {object} nil "Unauthorized to update user" // @Failure 500 {object} nil "Failed to find user | Failed to generate password hash | Failed to patch user | Failed to find userSettingList" // @Router /api/v1/user/{id} [PATCH] -func (s *APIV1Service) updateUser(c echo.Context) error { +func (s *APIV1Service) UpdateUser(c echo.Context) error { ctx := c.Request().Context() userID, err := util.ConvertStringToInt32(c.Param("id")) if err != nil { diff --git a/api/v1/user_setting.go b/api/v1/user_setting.go index e7755de8..0ba1dd32 100644 --- a/api/v1/user_setting.go +++ b/api/v1/user_setting.go @@ -79,12 +79,12 @@ type UpsertUserSettingRequest struct { } func (s *APIV1Service) registerUserSettingRoutes(g *echo.Group) { - g.POST("/user/setting", s.createUserSetting) + g.POST("/user/setting", s.UpsertUserSetting) } -// createUserSetting godoc +// UpsertUserSetting godoc // -// @Summary Create user setting +// @Summary Upsert user setting // @Tags user-setting // @Accept json // @Produce json @@ -95,7 +95,7 @@ func (s *APIV1Service) registerUserSettingRoutes(g *echo.Group) { // @Failure 500 {object} nil "Failed to upsert user setting" // @Security ApiKeyAuth // @Router /api/v1/user/setting [POST] -func (s *APIV1Service) createUserSetting(c echo.Context) error { +func (s *APIV1Service) UpsertUserSetting(c echo.Context) error { ctx := c.Request().Context() userID, ok := c.Get(auth.UserIDContextKey).(int32) if !ok { diff --git a/docs/api/auth.md b/docs/api/auth.md deleted file mode 100644 index 179db4ca..00000000 --- a/docs/api/auth.md +++ /dev/null @@ -1,107 +0,0 @@ -# Authentication APIs - -## Sign In - -``` -POST /api/v1/auth/signin -``` - -**Request Body** - -```json -{ - "username": "john", - "password": "password123" -} -``` - -**Response** - -```json -{ - "id": 123, - "username": "john", - "nickname": "John" - // other user fields -} -``` - -**Status Codes** - -- 200: Sign in success -- 400: Invalid request -- 401: Incorrect credentials -- 403: User banned -- 500: Internal server error - -## SSO Sign In - -``` -POST /api/v1/auth/signin/sso -``` - -**Request Body** - -```json -{ - "identityProviderId": 123, - "code": "abc123", - "redirectUri": "https://example.com/callback" -} -``` - -**Response** - -Same as **Sign In** - -**Status Codes** - -- 200: Success -- 400: Invalid request -- 401: Authentication failed -- 403: User banned -- 404: Identity provider not found -- 500: Internal server error - -## Sign Up - -``` -POST /api/v1/auth/signup -``` - -**Request Body** - -```json -{ - "username": "mary", - "password": "password456" -} -``` - -**Response** - -Same as **Sign In** - -**Status Codes** - -- 200: Sign up success -- 400: Invalid request -- 401: Sign up disabled -- 500: Internal server error - -## Sign Out - -``` -POST /api/v1/auth/signout -``` - -**Response** - -``` -true -``` - -**Status Codes** - -- 200: Success -- 500: Internal server error diff --git a/docs/api/how-to.md b/docs/api/how-to.md deleted file mode 100644 index ebc36283..00000000 --- a/docs/api/how-to.md +++ /dev/null @@ -1,44 +0,0 @@ -# Guide to Access Memos API with OpenID - -Memos API supports using OpenID as the user identifier to access the API. - -## What is OpenID - -OpenID is a unique identifier assigned by Memos system to each user. - -When a user registers or logs in via third-party OAuth through Memos system, the OpenID will be generated automatically. - -## How to Get User's OpenID - -You can get a user's OpenID through: - -- User checks the personal profile page in Memos system -- Calling Memos API to get user details -- Retrieving from login API response after successful login - -Example: - -``` -// GET /api/v1/user/me - -{ - "id": 123, - "username": "john", - "openId": "8613E04B4FA6603883F05A5E0A5E2517", - ... -} -``` - -## How to Use OpenID to Access API - -You can access the API on behalf of the user by appending `?openId=xxx` parameter to the API URL. - -For example: - -``` -curl 'https://demo.usememos.com/api/v1/memo?openId=8613E04B4FA6603883F05A5E0A5E2517' -H 'Content-Type: application/json' --data-raw '{"content":"Hello world!"}' -``` - -The above request will create a Memo under the user with OpenID `8613E04B4FA6603883F05A5E0A5E2517`. - -OpenID can be used in any API that requires user identity. diff --git a/docs/api/memo-relation.md b/docs/api/memo-relation.md deleted file mode 100644 index ff53882e..00000000 --- a/docs/api/memo-relation.md +++ /dev/null @@ -1,67 +0,0 @@ -# Memo Relation APIs - -## Create Memo Relation - -``` -POST /api/v1/memo/:memoId/relation -``` - -**Request Body** - -```json -{ - "relatedMemoId": 456, - "type": "REFERENCE" -} -``` - -**Response** - -```json -{ - "memoId": 123, - "relatedMemoId": 456, - "type": "REFERENCE" -} -``` - -**Status Codes** - -- 200: OK -- 400: Invalid request -- 500: Internal server error - -## Get Memo Relations - -``` -GET /api/v1/memo/:memoId/relation -``` - -**Response** - -```json -[ - { - "memoId": 123, - "relatedMemoId": 456, - "type": "REFERENCE" - } -] -``` - -**Status Codes** - -- 200: OK -- 500: Internal server error - -## Delete Memo Relation - -``` -DELETE /api/v1/memo/:memoId/relation/:relatedMemoId/type/:relationType -``` - -**Status Codes** - -- 200: Deleted -- 400: Invalid request -- 500: Internal server error diff --git a/docs/api/memo-resource.md b/docs/api/memo-resource.md deleted file mode 100644 index 819c57cf..00000000 --- a/docs/api/memo-resource.md +++ /dev/null @@ -1,65 +0,0 @@ -# Memo Resource APIs - -## Bind Resource to Memo - -``` -POST /api/v1/memo/:memoId/resource -``` - -**Request Body** - -```json -{ - "resourceId": 123 -} -``` - -**Response** - -``` -true -``` - -**Status Codes** - -- 200: OK -- 400: Invalid request -- 401: Unauthorized -- 404: Memo/Resource not found -- 500: Internal server error - -## Get Memo Resources - -``` -GET /api/v1/memo/:memoId/resource -``` - -**Response** - -```json -[ - { - "id": 123, - "filename": "example.png" - // other resource fields - } -] -``` - -**Status Codes** - -- 200: OK -- 500: Internal server error - -## Unbind Resource from Memo - -``` -DELETE /api/v1/memo/:memoId/resource/:resourceId -``` - -**Status Codes** - -- 200: OK -- 401: Unauthorized -- 404: Memo/Resource not found -- 500: Internal server error diff --git a/docs/api/memo.md b/docs/api/memo.md deleted file mode 100644 index f1952a6b..00000000 --- a/docs/api/memo.md +++ /dev/null @@ -1,136 +0,0 @@ -# Memo APIs - -## Create Memo - -``` -POST /api/v1/memo -``` - -**Request Body** - -```json -{ - "content": "Memo content", - "visibility": "PUBLIC", - "resourceIdList": [123, 456], - "relationList": [{ "relatedMemoId": 789, "type": "REFERENCE" }] -} -``` - -**Response** - -```json -{ - "id": 1234, - "content": "Memo content", - "visibility": "PUBLIC" - // other fields -} -``` - -**Status Codes** - -- 200: Created -- 400: Invalid request -- 401: Unauthorized -- 403: Forbidden to create public memo -- 500: Internal server error - -## Get Memo List - -``` -GET /api/v1/memo -``` - -**Parameters** - -- `creatorId` (optional): Filter by creator ID -- `visibility` (optional): Filter visibility, `PUBLIC`, `PROTECTED` or `PRIVATE` -- `rowStatus` (optional): Filter Status, `ARCHIVE`, `NORMAL`, Default `NORMAL` -- `pinned` (optional): Filter pinned memo, `true` or `false` -- `tag` (optional): Filter memo with tag -- `content` (optional): Search in content -- `limit` (optional): Limit number of results -- `offset` (optional): Offset of first result - -**Response** - -```json -[ - { - "id": 1234, - "content": "Memo 1" - // other fields - }, - { - "id": 5678, - "content": "Memo 2" - // other fields - } -] -``` - -## Get Memo By ID - -``` -GET /api/v1/memo/:memoId -``` - -**Response** - -```json -{ - "id": 1234, - "content": "Memo content" - // other fields -} -``` - -**Status Codes** - -- 200: Success -- 403: Forbidden for private memo -- 404: Not found -- 500: Internal server error - -## Update Memo - -``` -PATCH /api/v1/memo/:memoId -``` - -**Request Body** - -```json -{ - "content": "Updated content", - "visibility": "PRIVATE" -} -``` - -**Response** - -Same as **Get Memo By ID** - -**Status Codes** - -- 200: Updated -- 400: Invalid request -- 401: Unauthorized -- 403: Forbidden -- 404: Not found -- 500: Internal server error - -## Delete Memo - -``` -DELETE /api/v1/memo/:memoId -``` - -**Status Codes** - -- 200: Deleted -- 401: Unauthorized -- 403: Forbidden -- 404: Not found -- 500: Internal server error diff --git a/docs/api/resource.md b/docs/api/resource.md deleted file mode 100644 index 5d09c59c..00000000 --- a/docs/api/resource.md +++ /dev/null @@ -1,130 +0,0 @@ -# Resource APIs - -## Upload Resource - -### Upload File - -``` -POST /api/v1/resource/blob -``` - -**Request Form** - -- `file`: Upload file - -**Response** - -```json -{ - "id": 123, - "filename": "example.png" - // other fields -} -``` - -**Status Codes** - -- 200: OK -- 400: Invalid request -- 401: Unauthorized -- 413: File too large -- 500: Internal server error - -### Create Resource - -``` -POST /api/v1/resource -``` - -**Request Body** - -```json -{ - "filename": "example.png", - "externalLink": "https://example.com/image.png" -} -``` - -**Response** - -Same as **Upload File** - -**Status Codes** - -- 200: OK -- 400: Invalid request -- 401: Unauthorized -- 500: Internal server error - -## Get Resource List - -``` -GET /api/v1/resource -``` - -**Parameters** - -- `limit` (optional): Limit number of results -- `offset` (optional): Offset of first result - -**Response** - -```json -[ - { - "id": 123, - "filename": "example.png" - // other fields - }, - { - "id": 456, - "filename": "doc.pdf" - // other fields - } -] -``` - -**Status Codes** - -- 200: OK -- 401: Unauthorized -- 500: Internal server error - -## Update Resource - -``` -PATCH /api/v1/resource/:resourceId -``` - -**Request Body** - -```json -{ - "filename": "new_name.png" -} -``` - -**Response** - -Same as **Get Resource List** - -**Status Codes** - -- 200: OK -- 400: Invalid request -- 401: Unauthorized -- 404: Not found -- 500: Internal server error - -## Delete Resource - -``` -DELETE /api/v1/resource/:resourceId -``` - -**Status Codes** - -- 200: Deleted -- 401: Unauthorized -- 404: Not found -- 500: Internal server error diff --git a/docs/api/tag.md b/docs/api/tag.md deleted file mode 100644 index 4a376193..00000000 --- a/docs/api/tag.md +++ /dev/null @@ -1,84 +0,0 @@ -# Tag APIs - -## Create Tag - -``` -POST /api/v1/tag -``` - -**Request Body** - -```json -{ - "name": "python" -} -``` - -**Response** - -``` -"python" -``` - -**Status Codes** - -- 200: Created -- 400: Invalid request -- 500: Internal server error - -## Get Tag List - -``` -GET /api/v1/tag -``` - -**Response** - -```json -["python", "golang", "javascript"] -``` - -**Status Codes** - -- 200: OK -- 401: Unauthorized -- 500: Internal server error - -## Suggest Tags - -``` -GET /api/v1/tag/suggestion -``` - -**Response** - -```json -["django", "flask", "numpy"] -``` - -**Status Codes** - -- 200: OK -- 401: Unauthorized -- 500: Internal server error - -## Delete Tag - -``` -POST /api/v1/tag/delete -``` - -**Request Body** - -```json -{ - "name": "outdated_tag" -} -``` - -**Status Codes** - -- 200: Deleted -- 400: Invalid request -- 401: Unauthorized -- 500: Internal server error diff --git a/docs/api/user.md b/docs/api/user.md deleted file mode 100644 index 768f8ba6..00000000 --- a/docs/api/user.md +++ /dev/null @@ -1,164 +0,0 @@ -# User APIs - -## Create User - -``` -POST /api/v1/user -``` - -**Request Body** - -```json -{ - "username": "john", - "role": "USER", - "email": "john@example.com", - "nickname": "John", - "password": "password123" -} -``` - -**Response** - -```json -{ - "id": 123, - "username": "john", - "role": "USER", - "email": "john@example.com", - "nickname": "John", - "avatarUrl": "", - "createdTs": 1596647800, - "updatedTs": 1596647800 -} -``` - -**Status Codes** - -- 200: Success -- 400: Validation error -- 401: Unauthorized -- 403: Forbidden to create host user -- 500: Internal server error - -## Get User List - -``` -GET /api/v1/user -``` - -**Response** - -```json -[ - { - "id": 123, - "username": "john", - "role": "USER" - // other fields - }, - { - "id": 456, - "username": "mary", - "role": "ADMIN" - // other fields - } -] -``` - -**Status Codes** - -- 200: Success -- 500: Internal server error - -## Get User By ID - -``` -GET /api/v1/user/:id -``` - -**Response** - -```json -{ - "id": 123, - "username": "john", - "role": "USER" - // other fields -} -``` - -**Status Codes** - -- 200: Success -- 404: Not found -- 500: Internal server error - -## Update User - -``` -PATCH /api/v1/user/:id -``` - -**Request Body** - -```json -{ - "username": "johnny", - "email": "johnny@example.com", - "nickname": "Johnny", - "avatarUrl": "https://avatars.example.com/u=123" -} -``` - -**Response** - -```json -{ - "id": 123, - "username": "johnny", - "role": "USER", - "email": "johnny@example.com", - "nickname": "Johnny", - "avatarUrl": "https://avatars.example.com/u=123", - "createdTs": 1596647800, - "updatedTs": 1596647900 -} -``` - -**Status Codes** - -- 200: Success -- 400: Validation error -- 403: Forbidden -- 404: Not found -- 500: Internal server error - -## Delete User - -``` -DELETE /api/v1/user/:id -``` - -**Status Codes** - -- 200: Success -- 403: Forbidden -- 404: Not found -- 500: Internal server error - -## Get Current User - -``` -GET /api/v1/user/me -``` - -**Response** - -Same as **Get User By ID** - -**Status Codes** - -- 200: Success -- 401: Unauthorized -- 500: Internal server error diff --git a/docs/documenting-the-api.md b/docs/documenting-the-api.md index d5eaeab7..c1e34784 100644 --- a/docs/documenting-the-api.md +++ b/docs/documenting-the-api.md @@ -37,8 +37,8 @@ 2. Run one of the following provided scripts: - - Linux: `./scripts/generate-api-documentation.sh` (remember to `chmod +x` the script first) - - Windows: `./scripts/generate-api-documentation.ps1` + - Linux: `./scripts/gen-api-v1-docs.sh` (remember to `chmod +x` the script first) + - Windows: `./scripts/gen-api-v1-docs.ps1` > The scripts will install swag if needed (via go install), then run `swag fmt` and `swag init` commands. @@ -48,7 +48,7 @@ - If you reference a custom Go struct from outside the API file, use a relative definition, like `store.IdentityProvider`. This works because `./` is passed to swag at `--dir` argument. If swag can't resolve the reference, it will fail. -- If the API grows or you need to reference some type from another location, remember to update ./scripts/generate-api-documentation.cfg file with the new paths. +- If the API grows or you need to reference some type from another location, remember to update ./scripts/gen-api-v1-docs.cfg file with the new paths. - It's possible to list multiple errors for the same code using enum-like structs, that will show a proper, spec-conformant model with all entries at Swagger-UI. The drawback is that this approach requires a major refactoring and will add a lot of boilerplate code, as there are inconsistencies between API methods error responses. diff --git a/scripts/generate-api-documentation.cfg b/scripts/gen-api-v1-docs.cfg similarity index 74% rename from scripts/generate-api-documentation.cfg rename to scripts/gen-api-v1-docs.cfg index c02b20a6..6cf35928 100644 --- a/scripts/generate-api-documentation.cfg +++ b/scripts/gen-api-v1-docs.cfg @@ -1,4 +1,4 @@ -# This file is used by generate-api-documentation.ps1 and generate-api-documentation.sh +# This file is used by gen-api-v1-docs.ps1 and gen-api-v1-docs.sh # You should list aditional dirs here if the API grows SWAG_API_DIRS=./api/v1 @@ -10,4 +10,4 @@ SWAG_GENERAL_INFO=./server/server.go SWAG_OUTPUT_TYPES=go,yaml # Where generated files are outputted -SWAG_OUTPUT=./api +SWAG_OUTPUT=./api/v1 diff --git a/scripts/generate-api-documentation.ps1 b/scripts/gen-api-v1-docs.ps1 similarity index 87% rename from scripts/generate-api-documentation.ps1 rename to scripts/gen-api-v1-docs.ps1 index 8dd163a3..4b80c10f 100644 --- a/scripts/generate-api-documentation.ps1 +++ b/scripts/gen-api-v1-docs.ps1 @@ -7,10 +7,10 @@ # Requirements: # * go -# swag is configured mainly via generate-api-documentation.cfg file. +# swag is configured mainly via gen-api-v1-docs.cfg file. # Usage: -# ./scripts/generate-api-documentation.ps1 +# ./scripts/gen-api-v1-docs.ps1 foreach ($dir in @(".", "../")) { if (Test-Path (Join-Path $dir ".gitignore")) { @@ -20,8 +20,8 @@ foreach ($dir in @(".", "../")) { } Set-Location $repoRoot -Write-Host "Parsing generate-api-documentation.cfg..." -foreach ($line in (Get-Content "$repoRoot\scripts\generate-api-documentation.cfg" )) { +Write-Host "Parsing gen-api-v1-docs.cfg..." +foreach ($line in (Get-Content "$repoRoot\scripts\gen-api-v1-docs.cfg" )) { if ($line.Trim().StartsWith('#')) { continue } diff --git a/scripts/generate-api-documentation.sh b/scripts/gen-api-v1-docs.sh similarity index 91% rename from scripts/generate-api-documentation.sh rename to scripts/gen-api-v1-docs.sh index d606d144..69236850 100755 --- a/scripts/generate-api-documentation.sh +++ b/scripts/gen-api-v1-docs.sh @@ -9,11 +9,11 @@ # Requirements: # * go -# swag is configured via generate-api-documentation.cfg file. +# swag is configured via gen-api-v1-docs.cfg file. # Usage: -# chmod +x ./scripts/generate-api-documentation.sh -# ./scripts/generate-api-documentation.sh +# chmod +x ./scripts/gen-api-v1-docs.sh +# ./scripts/gen-api-v1-docs.sh find_repo_root() { # Usage: find_repo_root ... @@ -59,8 +59,8 @@ else fi cd $repo_root -echo "Parsing generate-api-documentation.cfg..." -source "$repo_root/scripts/generate-api-documentation.cfg" +echo "Parsing gen-api-v1-docs.cfg..." +source "$repo_root/scripts/gen-api-v1-docs.cfg" echo -e "API directories: \033[0;34m$SWAG_API_DIRS\033[0m" echo -e "Output directory: \033[0;34m$SWAG_OUTPUT\033[0m" diff --git a/server/server.go b/server/server.go index 292a89b7..17d39528 100644 --- a/server/server.go +++ b/server/server.go @@ -13,7 +13,6 @@ import ( "github.com/labstack/echo/v4/middleware" "github.com/pkg/errors" echoSwagger "github.com/swaggo/echo-swagger" - api "github.com/usememos/memos/api" apiv1 "github.com/usememos/memos/api/v1" apiv2 "github.com/usememos/memos/api/v2" "github.com/usememos/memos/common/log" @@ -60,9 +59,6 @@ type Server struct { // @name openId // @description Insert your Open ID API Key here. func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store) (*Server, error) { - // programmatically set API version same as the server version - api.SwaggerInfo.Version = profile.Version - e := echo.New() e.Debug = true e.HideBanner = true @@ -153,6 +149,9 @@ func (s *Server) Start(ctx context.Context) error { } }() + // programmatically set API version same as the server version + apiv1.SwaggerInfo.Version = s.Profile.Version + return s.e.Start(fmt.Sprintf(":%d", s.Profile.Port)) }