feat: 添加评价微服务,支持密封互评与订单状态联动
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
Name: review-api
|
||||
Host: 0.0.0.0
|
||||
Port: 8888
|
||||
|
||||
Prometheus:
|
||||
Host: 0.0.0.0
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONFIG =====
|
||||
ReviewRpcConf:
|
||||
Endpoints:
|
||||
- review-rpc:8080
|
||||
OrderRpcConf:
|
||||
Endpoints:
|
||||
- order-rpc:8080
|
||||
@@ -0,0 +1,12 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
rest.RestConf
|
||||
ReviewRpcConf zrpc.RpcClientConf
|
||||
OrderRpcConf zrpc.RpcClientConf
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package review
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"juwan-backend/app/review/api/internal/logic/review"
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
)
|
||||
|
||||
// 获取订单评价
|
||||
func GetOrderReviewsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.GetOrderReviewsReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := review.NewGetOrderReviewsLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetOrderReviews(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package review
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"juwan-backend/app/review/api/internal/logic/review"
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
)
|
||||
|
||||
// 获取公开评价列表
|
||||
func ListReviewsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.PageReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := review.NewListReviewsLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ListReviews(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package review
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"juwan-backend/app/review/api/internal/logic/review"
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
)
|
||||
|
||||
// 获取用户收到的评价
|
||||
func ListUserReviewsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ListUserReviewsReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := review.NewListUserReviewsLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ListUserReviews(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package review
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"juwan-backend/app/review/api/internal/logic/review"
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
)
|
||||
|
||||
// 提交评价
|
||||
func SubmitReviewHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.SubmitReviewReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := review.NewSubmitReviewLogic(r.Context(), svcCtx)
|
||||
resp, err := l.SubmitReview(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.10.1
|
||||
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
review "juwan-backend/app/review/api/internal/handler/review"
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// 提交评价
|
||||
Method: http.MethodPost,
|
||||
Path: "/orders/:id/review",
|
||||
Handler: review.SubmitReviewHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 获取订单评价
|
||||
Method: http.MethodGet,
|
||||
Path: "/orders/:id/reviews",
|
||||
Handler: review.GetOrderReviewsHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/v1"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
// 获取公开评价列表
|
||||
Method: http.MethodGet,
|
||||
Path: "/reviews",
|
||||
Handler: review.ListReviewsHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 获取用户收到的评价
|
||||
Method: http.MethodGet,
|
||||
Path: "/users/:id/reviews",
|
||||
Handler: review.ListUserReviewsHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/v1"),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package review
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
reviewpb "juwan-backend/app/review/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetOrderReviewsLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 获取订单评价
|
||||
func NewGetOrderReviewsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetOrderReviewsLogic {
|
||||
return &GetOrderReviewsLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetOrderReviewsLogic) GetOrderReviews(req *types.GetOrderReviewsReq) (resp *types.ReviewListResp, err error) {
|
||||
orderId := req.Id
|
||||
result, err := l.svcCtx.ReviewRpc.SearchReviews(l.ctx, &reviewpb.SearchReviewsReq{
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
OrderId: &orderId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]types.Review, 0, len(result.GetReviews()))
|
||||
for _, r := range result.GetReviews() {
|
||||
items = append(items, toAPIReview(r))
|
||||
}
|
||||
return &types.ReviewListResp{
|
||||
Items: items,
|
||||
Meta: types.PageMeta{
|
||||
Total: int64(len(items)),
|
||||
Offset: 0,
|
||||
Limit: 10,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package review
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
reviewpb "juwan-backend/app/review/rpc/pb"
|
||||
)
|
||||
|
||||
func formatUnix(ts int64) string {
|
||||
if ts <= 0 {
|
||||
return ""
|
||||
}
|
||||
return time.Unix(ts, 0).UTC().Format(time.RFC3339)
|
||||
}
|
||||
|
||||
func toAPIReview(r *reviewpb.Reviews) types.Review {
|
||||
return types.Review{
|
||||
Id: r.GetId(),
|
||||
OrderId: r.GetOrderId(),
|
||||
FromUserId: r.GetFromUserId(),
|
||||
FromUserName: r.GetFromUserName(),
|
||||
Rating: int(r.GetRating()),
|
||||
Content: r.GetContent(),
|
||||
Sealed: r.GetSealed(),
|
||||
CreatedAt: formatUnix(r.GetCreatedAt()),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package review
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
reviewpb "juwan-backend/app/review/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ListReviewsLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 获取公开评价列表
|
||||
func NewListReviewsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListReviewsLogic {
|
||||
return &ListReviewsLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ListReviewsLogic) ListReviews(req *types.PageReq) (resp *types.ReviewListResp, err error) {
|
||||
sealed := false
|
||||
result, err := l.svcCtx.ReviewRpc.SearchReviews(l.ctx, &reviewpb.SearchReviewsReq{
|
||||
Offset: req.Offset,
|
||||
Limit: req.Limit,
|
||||
Sealed: &sealed,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]types.Review, 0, len(result.GetReviews()))
|
||||
for _, r := range result.GetReviews() {
|
||||
items = append(items, toAPIReview(r))
|
||||
}
|
||||
return &types.ReviewListResp{
|
||||
Items: items,
|
||||
Meta: types.PageMeta{
|
||||
Total: int64(len(items)),
|
||||
Offset: req.Offset,
|
||||
Limit: req.Limit,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package review
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
reviewpb "juwan-backend/app/review/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ListUserReviewsLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 获取用户收到的评价
|
||||
func NewListUserReviewsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListUserReviewsLogic {
|
||||
return &ListUserReviewsLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ListUserReviewsLogic) ListUserReviews(req *types.ListUserReviewsReq) (resp *types.ReviewListResp, err error) {
|
||||
sealed := false
|
||||
toUserId := req.Id
|
||||
result, err := l.svcCtx.ReviewRpc.SearchReviews(l.ctx, &reviewpb.SearchReviewsReq{
|
||||
Offset: req.Offset,
|
||||
Limit: req.Limit,
|
||||
ToUserId: &toUserId,
|
||||
Sealed: &sealed,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]types.Review, 0, len(result.GetReviews()))
|
||||
for _, r := range result.GetReviews() {
|
||||
items = append(items, toAPIReview(r))
|
||||
}
|
||||
return &types.ReviewListResp{
|
||||
Items: items,
|
||||
Meta: types.PageMeta{
|
||||
Total: int64(len(items)),
|
||||
Offset: req.Offset,
|
||||
Limit: req.Limit,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package review
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"juwan-backend/app/order/rpc/orderservice"
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
"juwan-backend/app/review/api/internal/types"
|
||||
reviewpb "juwan-backend/app/review/rpc/pb"
|
||||
"juwan-backend/common/utils/contextj"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type SubmitReviewLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewSubmitReviewLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SubmitReviewLogic {
|
||||
return &SubmitReviewLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SubmitReviewLogic) SubmitReview(req *types.SubmitReviewReq) (resp *types.EmptyResp, err error) {
|
||||
uid, err := contextj.UserIDFrom(l.ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orderResp, err := l.svcCtx.OrderRpc.GetOrdersById(l.ctx, &orderservice.GetOrdersByIdReq{Id: req.Id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
order := orderResp.GetOrders()
|
||||
if order == nil {
|
||||
return nil, errors.New("order not found")
|
||||
}
|
||||
if order.GetStatus() != "pending_review" {
|
||||
return nil, errors.New("order is not in pending_review status")
|
||||
}
|
||||
|
||||
var fromUserId, toUserId int64
|
||||
if uid == order.GetConsumerId() {
|
||||
fromUserId = order.GetConsumerId()
|
||||
toUserId = order.GetPlayerId()
|
||||
} else if uid == order.GetPlayerId() {
|
||||
fromUserId = order.GetPlayerId()
|
||||
toUserId = order.GetConsumerId()
|
||||
} else {
|
||||
return nil, errors.New("not a participant of this order")
|
||||
}
|
||||
|
||||
_, err = l.svcCtx.ReviewRpc.AddReviews(l.ctx, &reviewpb.AddReviewsReq{
|
||||
OrderId: req.Id,
|
||||
FromUserId: fromUserId,
|
||||
ToUserId: toUserId,
|
||||
Rating: int32(req.Rating),
|
||||
Content: req.Content,
|
||||
Sealed: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existing, err := l.svcCtx.ReviewRpc.SearchReviews(l.ctx, &reviewpb.SearchReviewsReq{
|
||||
Offset: 0,
|
||||
Limit: 2,
|
||||
OrderId: &req.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(existing.GetReviews()) >= 2 {
|
||||
now := time.Now().Unix()
|
||||
sealed := false
|
||||
for _, r := range existing.GetReviews() {
|
||||
_, _ = l.svcCtx.ReviewRpc.UpdateReviews(l.ctx, &reviewpb.UpdateReviewsReq{
|
||||
Id: r.GetId(),
|
||||
Sealed: &sealed,
|
||||
UnsealedAt: &now,
|
||||
})
|
||||
}
|
||||
|
||||
completedStatus := "completed"
|
||||
completedAt := now
|
||||
updatedAt := now
|
||||
_, _ = l.svcCtx.OrderRpc.UpdateOrders(l.ctx, &orderservice.UpdateOrdersReq{
|
||||
Id: req.Id,
|
||||
Status: &completedStatus,
|
||||
CompletedAt: &completedAt,
|
||||
UpdatedAt: &updatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
return &types.EmptyResp{}, nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"juwan-backend/app/order/rpc/orderservice"
|
||||
"juwan-backend/app/review/api/internal/config"
|
||||
"juwan-backend/app/review/rpc/reviewservice"
|
||||
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
ReviewRpc reviewservice.ReviewService
|
||||
OrderRpc orderservice.OrderService
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
ReviewRpc: reviewservice.NewReviewService(zrpc.MustNewClient(c.ReviewRpcConf)),
|
||||
OrderRpc: orderservice.NewOrderService(zrpc.MustNewClient(c.OrderRpcConf)),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.10.1
|
||||
|
||||
package types
|
||||
|
||||
type EmptyResp struct {
|
||||
}
|
||||
|
||||
type GetOrderReviewsReq struct {
|
||||
ReviewPathId
|
||||
}
|
||||
|
||||
type ListUserReviewsReq struct {
|
||||
ReviewPathId
|
||||
PageReq
|
||||
}
|
||||
|
||||
type PageMeta struct {
|
||||
Total int64 `json:"total"`
|
||||
Offset int64 `json:"offset"`
|
||||
Limit int64 `json:"limit"`
|
||||
}
|
||||
|
||||
type PageReq struct {
|
||||
Offset int64 `form:"offset,default=0"`
|
||||
Limit int64 `form:"limit,default=20"`
|
||||
}
|
||||
|
||||
type Review struct {
|
||||
Id int64 `json:"id"`
|
||||
OrderId int64 `json:"orderId"`
|
||||
FromUserId int64 `json:"fromUserId"`
|
||||
FromUserName string `json:"fromUserName"`
|
||||
Rating int `json:"rating"`
|
||||
Content string `json:"content"`
|
||||
Sealed bool `json:"sealed"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
|
||||
type ReviewListResp struct {
|
||||
Items []Review `json:"items"`
|
||||
Meta PageMeta `json:"meta"`
|
||||
}
|
||||
|
||||
type ReviewPathId struct {
|
||||
Id int64 `path:"id"`
|
||||
}
|
||||
|
||||
type SimpleUser struct {
|
||||
Id string `json:"id"`
|
||||
Nickname string `json:"nickname"`
|
||||
Avatar string `json:"avatar"`
|
||||
}
|
||||
|
||||
type SubmitReviewReq struct {
|
||||
ReviewPathId
|
||||
Rating int `json:"rating"`
|
||||
Content string `json:"content,optional"`
|
||||
}
|
||||
|
||||
type UserProfile struct {
|
||||
Id string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Nickname string `json:"nickname"`
|
||||
Avatar string `json:"avatar"`
|
||||
Role string `json:"role"` // consumer, player, owner, admin
|
||||
VerifiedRoles []string `json:"verifiedRoles"`
|
||||
VerificationStatus map[string]string `json:"verificationStatus"`
|
||||
Phone string `json:"phone,optional"`
|
||||
Bio string `json:"bio,optional"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"juwan-backend/app/review/api/internal/config"
|
||||
"juwan-backend/app/review/api/internal/handler"
|
||||
"juwan-backend/app/review/api/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/review-api.yaml", "the config file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
defer server.Stop()
|
||||
|
||||
ctx := svc.NewServiceContext(c)
|
||||
handler.RegisterHandlers(server, ctx)
|
||||
|
||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||
server.Start()
|
||||
}
|
||||
Reference in New Issue
Block a user