261 lines
7.4 KiB
Go
261 lines
7.4 KiB
Go
|
/*
|
|||
|
* Copyright (c) 2020 Alex <alex@webz.asia>
|
|||
|
*
|
|||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|||
|
* you may not use this file except in compliance with the License.
|
|||
|
* You may obtain a copy of the License at
|
|||
|
*
|
|||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
|
*
|
|||
|
* Unless required by applicable law or agreed to in writing, software
|
|||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
|
* See the License for the specific language governing permissions and
|
|||
|
* limitations under the License.
|
|||
|
*
|
|||
|
* @author Alex <alex@webz.asia>
|
|||
|
* @copyright Copyright (c) 2020 Alex <alex@webz.asia>
|
|||
|
* @since 29.12.2020
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
package dtoLib
|
|||
|
|
|||
|
import (
|
|||
|
"errors"
|
|||
|
"fmt"
|
|||
|
"net/http"
|
|||
|
"net/url"
|
|||
|
|
|||
|
"github.com/go-convert/fields"
|
|||
|
)
|
|||
|
|
|||
|
type PaginationContainer struct {
|
|||
|
Pagination Pagination `json:"pagination"`
|
|||
|
}
|
|||
|
|
|||
|
type Pagination struct {
|
|||
|
Page int `json:"page"`
|
|||
|
PerPage int `json:"per_page"`
|
|||
|
Total int `json:"total"`
|
|||
|
}
|
|||
|
|
|||
|
type ApiResponse struct {
|
|||
|
Code int32 `json:"code"`
|
|||
|
Type string `json:"type"`
|
|||
|
Message string `json:"message"`
|
|||
|
Data interface{} `json:"data"`
|
|||
|
*PaginationContainer
|
|||
|
}
|
|||
|
|
|||
|
type ApiErrorResponse struct {
|
|||
|
Code int32 `json:"code"`
|
|||
|
Type string `json:"type"`
|
|||
|
Message string `json:"message"`
|
|||
|
Errors []error `json:"errors"`
|
|||
|
Data interface{} `json:"data"`
|
|||
|
}
|
|||
|
|
|||
|
type SearchParams url.Values
|
|||
|
|
|||
|
// AllApiResponses returns full map of map ApiResponse structure
|
|||
|
func AllApiResponses() map[string]map[string]ApiResponse {
|
|||
|
return responseMap
|
|||
|
}
|
|||
|
|
|||
|
// AddNewApiResponse adds new api response by name, returns error if already exists
|
|||
|
func AddNewApiResponse(name string, response map[string]ApiResponse) error {
|
|||
|
if _, ok := responseMap[name]; ok {
|
|||
|
return errors.New("this name already exists")
|
|||
|
}
|
|||
|
responseMap[name] = response
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
// AllApiErrorResponses returns full map of map ApiErrorResponse structure
|
|||
|
func AllApiErrorResponses() map[string]map[string]ApiErrorResponse {
|
|||
|
return errorResponseMap
|
|||
|
}
|
|||
|
|
|||
|
// AddNewApiErrorResponse adds new error api response by name, returns error if already exists
|
|||
|
func AddNewApiErrorResponse(name string, response map[string]ApiErrorResponse) error {
|
|||
|
if _, ok := errorResponseMap[name]; ok {
|
|||
|
return errors.New("this name already exists")
|
|||
|
}
|
|||
|
errorResponseMap[name] = response
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
// NotCreated returns http response code and error response object
|
|||
|
func NotCreated(name string, errors []error) (int, ApiErrorResponse) {
|
|||
|
response, ok := errorResponseMap[name][StatusNotCreated]
|
|||
|
if ok {
|
|||
|
response.Errors = errors
|
|||
|
if len(errors) == 1 {
|
|||
|
response.Data = errors[0].Error()
|
|||
|
}
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailedError(name, errors)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusNotAcceptable, response
|
|||
|
}
|
|||
|
|
|||
|
// Created returns http response code and regular response object
|
|||
|
func Created(name string, data interface{}) (int, ApiResponse) {
|
|||
|
response, ok := responseMap[name][StatusCreated]
|
|||
|
if ok {
|
|||
|
response.Data = data
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailed(name)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusCreated, response
|
|||
|
}
|
|||
|
|
|||
|
// NotUpdated returns http response code and error response object
|
|||
|
func NotUpdated(name string, errors []error) (int, ApiErrorResponse) {
|
|||
|
response, ok := errorResponseMap[name][StatusNotUpdated]
|
|||
|
if ok {
|
|||
|
response.Errors = errors
|
|||
|
if len(errors) == 1 {
|
|||
|
response.Data = errors[0].Error()
|
|||
|
}
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailedError(name, errors)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusNotAcceptable, response
|
|||
|
}
|
|||
|
|
|||
|
// Updated returns http response code and regular response object
|
|||
|
func Updated(name string, data interface{}) (int, ApiResponse) {
|
|||
|
response, ok := responseMap[name][StatusUpdated]
|
|||
|
if ok {
|
|||
|
response.Data = data
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailed(name)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusAccepted, response
|
|||
|
}
|
|||
|
|
|||
|
// NotDeleted returns http response code and error response object
|
|||
|
func NotDeleted(name string, errors []error) (int, ApiErrorResponse) {
|
|||
|
response, ok := errorResponseMap[name][StatusNotDeleted]
|
|||
|
if ok {
|
|||
|
response.Errors = errors
|
|||
|
if len(errors) == 1 {
|
|||
|
response.Data = errors[0].Error()
|
|||
|
}
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailedError(name, errors)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusNotFound, response
|
|||
|
}
|
|||
|
|
|||
|
// Deleted returns http response code and regular response object
|
|||
|
func Deleted(name string, data interface{}) (int, ApiResponse) {
|
|||
|
response, ok := responseMap[name][StatusDeleted]
|
|||
|
if ok {
|
|||
|
response.Data = data
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailed(name)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusOK, response
|
|||
|
}
|
|||
|
|
|||
|
// NotFound returns http response code and error response object
|
|||
|
func NotFound(name string, errors []error) (int, ApiErrorResponse) {
|
|||
|
response, ok := errorResponseMap[name][StatusNotFound]
|
|||
|
if ok {
|
|||
|
response.Errors = errors
|
|||
|
if len(errors) == 1 {
|
|||
|
response.Data = errors[0].Error()
|
|||
|
}
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailedError(name, errors)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusNotFound, response
|
|||
|
}
|
|||
|
|
|||
|
// Found returns http response code and regular response object(found data and pagination)
|
|||
|
func Found(name string, data interface{}, pagination interface{}) (int, ApiResponse) {
|
|||
|
response, ok := responseMap[name][StatusFound]
|
|||
|
if ok {
|
|||
|
response.Data = data
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailed(name)
|
|||
|
}
|
|||
|
|
|||
|
if nil != pagination {
|
|||
|
dtoPagination := &Pagination{}
|
|||
|
fields.Сonvert(pagination, "pagination", dtoPagination)
|
|||
|
response.PaginationContainer = &PaginationContainer{Pagination: *dtoPagination}
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusOK, response
|
|||
|
}
|
|||
|
|
|||
|
// Ok returns http response code and regular response object
|
|||
|
func Ok(name string, data interface{}) (int, ApiResponse) {
|
|||
|
response, ok := responseMap[name][StatusOk]
|
|||
|
if ok {
|
|||
|
response.Data = data
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailed(name)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusOK, response
|
|||
|
}
|
|||
|
|
|||
|
// Failed returns http response code and error response object
|
|||
|
func Failed(name string, errors []error) (int, ApiErrorResponse) {
|
|||
|
response, ok := errorResponseMap[name][StatusFailed]
|
|||
|
if ok {
|
|||
|
response.Errors = errors
|
|||
|
if len(errors) == 1 {
|
|||
|
response.Data = errors[0].Error()
|
|||
|
}
|
|||
|
} else {
|
|||
|
// fallback to other response, have to support it by default
|
|||
|
return FallbackToFailedError(name, errors)
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusInternalServerError, response
|
|||
|
}
|
|||
|
|
|||
|
// FallbackToFailedError returns http response code and error response object as a fallback to predefined failed error response
|
|||
|
func FallbackToFailedError(name string, errs []error) (int, ApiErrorResponse) {
|
|||
|
errs = append(errs, fmt.Errorf("fallback to failed - no proper response for '%s' type", name))
|
|||
|
response := errorResponseMap[TypeSystem][StatusFailed]
|
|||
|
response.Errors = errs
|
|||
|
if len(errs) == 1 {
|
|||
|
response.Data = errs[0].Error()
|
|||
|
}
|
|||
|
|
|||
|
return http.StatusInternalServerError, response
|
|||
|
}
|
|||
|
|
|||
|
// FallbackToFailed returns http response code and regular response object as a fallback to predefined failed response
|
|||
|
func FallbackToFailed(name string) (int, ApiResponse) {
|
|||
|
response := responseMap[TypeSystem][StatusFailed]
|
|||
|
response.Data = fmt.Errorf("fallback to failed - no proper response for '%s' type", name).(interface{})
|
|||
|
|
|||
|
return http.StatusInternalServerError, response
|
|||
|
}
|