当前位置:网站首页>Micro, m3o micro service series (II)
Micro, m3o micro service series (II)
2022-07-18 13:42:00 【Bai,】
micro Build blog
Make sure micro server Run in another terminal , And we have connected to it , That is, run the microserver
[[email protected] M3O]# micro server
2022-07-15 20:49:01 file=server/server.go:88 level=info Starting server
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering registry
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering broker
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering network
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering runtime
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering config
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering store
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering events
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering auth
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering proxy
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering api
2022-07-15 20:49:01 file=server/server.go:116 level=info Registering web
2022-07-15 20:49:01 file=server/server.go:206 level=info Starting server runtime
Check our local environment
[[email protected] ~]# micro env
* local 127.0.0.1:8081 Local running Micro Server
platform proxy.m3o.com Cloud hosted Micro Platform
If it's not the local environment , function
micro env set local
Create as a service item :
[[email protected] ~]# micro new ports
Creating service ports
.
├── micro.mu
├── main.go
├── generate.go
├── handler
│ └── ports.go
├── proto
│ └── ports.proto
├── Dockerfile
├── Makefile
├── README.md
├── .gitignore
└── go.mod
download protoc zip packages (protoc-$VERSION-$PLATFORM.zip) and install:
visit https://github.com/protocolbuffers/protobuf/releases
compile the proto file ports.proto:
cd ports
make init
go mod vendor
make proto
[[email protected] ~]# ls ports
Dockerfile generate.go go.mod handler main.go Makefile micro.mu proto README.md
need 3 Methods :
Save For blog insert and update
Query For reading and listing
Delete Delete
from ports Start :
ports.proto:
syntax = "proto3";
//option go_package="./;posts";
package posts;
service Posts {
rpc Save(SaveRequest) returns (SaveResponse) {
}
rpc Query(QueryRequest) returns (QueryResponse) {
}
rpc Delete(DeleteRequest) returns (DeleteResponse) {
}
}
message SaveRequest {
string id = 1;
string title = 2;
string slug = 3;
string content = 4;
int64 timestamp = 5;
repeated string tags = 6;
}
message SaveResponse {
string id = 1;
}
message Post {
string id = 1;
string title = 2;
string slug = 3;
string content = 4;
int64 created = 5;
int64 updated = 6;
string author = 7;
repeated string tags = 8;
}
// Query posts. Acts as a listing when no id or slug provided.
// Gets a single post by id or slug if any of them provided.
message QueryRequest {
string id = 1;
string slug = 2;
string tag = 3;
int64 offset = 4;
int64 limit = 5;
}
message QueryResponse {
repeated Post posts = 1;
}
message DeleteRequest {
string id = 1;
}
message DeleteResponse {
}
Although we have defined Post Message type , But we still redefine some fields as the top-level fields of the message type SaveRequest. The main reason is that we don't want Dynamic command
If we embed Post post = 1 To SaveRequest, We will call the post service in the following ways :
micro posts save --post_title=Title --post_content=Content
But we don't want to repeat post, Our first choice is :
micro posts save --title=Title --content=Content
To rebuild proto, We have to make proto Issue the command in the project root directory .
Next to the main.go:
package main
import (
"posts/handler"
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"
)
func main() {
// Create the service
srv := service.New(
service.Name("posts"),
)
// Register Handler
srv.Handle(handler.NewPosts())
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}
posts.go:
package handler
import (
"context"
"time"
"github.com/micro/dev/model"
"github.com/micro/go-micro/errors"
"github.com/micro/micro/v3/service/logger"
"github.com/micro/micro/v3/service/store"
proto "posts/proto"
"github.com/gosimple/slug"
)
type Posts struct {
db model.Model
idIndex model.Index
createdIndex model.Index
slugIndex model.Index
}
func NewPosts() *Posts {
createdIndex := model.ByEquality("created")
createdIndex.Order.Type = model.OrderTypeDesc
slugIndex := model.ByEquality("slug")
idIndex := model.ByEquality("id")
idIndex.Order.Type = model.OrderTypeUnordered
return &Posts{
db: model.New(
store.DefaultStore,
"posts",
model.Indexes(slugIndex, createdIndex),
&model.ModelOptions{
IdIndex: idIndex,
},
),
createdIndex: createdIndex,
slugIndex: slugIndex,
idIndex: idIndex,
}
}
func (p *Posts) Save(ctx context.Context, req *proto.SaveRequest, rsp *proto.SaveResponse) error {
logger.Info("Received Posts.Save request")
post := &proto.Post{
Id: req.Id,
Title: req.Title,
Content: req.Content,
Slug: req.Slug,
Created: time.Now().Unix(),
}
if req.Slug == "" {
post.Slug = slug.Make(req.Title)
}
return p.db.Save(post)
}
func (p *Posts) Query(ctx context.Context, req *proto.QueryRequest, rsp *proto.QueryResponse) error {
var q model.Query
if len(req.Slug) > 0 {
logger.Infof("Reading post by slug: %v", req.Slug)
q = p.slugIndex.ToQuery(req.Slug)
} else if len(req.Id) > 0 {
logger.Infof("Reading post by id: %v", req.Id)
q = p.idIndex.ToQuery(req.Id)
} else {
q = p.createdIndex.ToQuery(nil)
var limit uint
limit = 20
if req.Limit > 0 {
limit = uint(req.Limit)
}
q.Limit = int64(limit)
q.Offset = req.Offset
logger.Infof("Listing posts, offset: %v, limit: %v", req.Offset, limit)
}
posts := []*proto.Post{
}
err := p.db.List(q, &posts)
if err != nil {
return errors.BadRequest("proto.query.store-read", "Failed to read from store: %v", err.Error())
}
rsp.Posts = posts
return nil
}
func (p *Posts) Delete(ctx context.Context, req *proto.DeleteRequest, rsp *proto.DeleteResponse) error {
logger.Info("Received Post.Delete request")
return p.db.Delete(model.Equals("id", req.Id))
}
The above code uses Model Package. It sets the index , Enable us to query data , And tell the model to maintain these indexes .
1. need id Index can pass id Read
2. Need to create index , So when we list Posts , The order of posts will be descending according to the fields created
3. need slug Index can pass slug Read the post ( namely .myblog.com/post/awesome-post-url)
here micro run . Our post service should be deployed in the project root directory . Let's verify micro logs posts( The exact output may depend on the actual configuration format configuration )
Save post
func (p *Posts) Save(ctx context.Context, req *proto.SaveRequest, rsp *proto.SaveResponse) error {
logger.Info("Received Posts.Save request")
post := &proto.Post{
Id: req.Id,
Title: req.Title,
Content: req.Content,
Slug: req.Slug,
Created: time.Now().Unix(),
}
if req.Slug == "" {
post.Slug = slug.Make(req.Title)
}
return p.db.Save(post)
}
[[email protected] handler]# micro posts save --id=1 --title="Post one" --content="First saved post"
{
}
[[email protected] handler]# micro posts save --id=2 --title="Post two" --content="Second saved post"
{
}
Query posts
The query handler can pass id、slug Query and enable the post list
func (p *Posts) Query(ctx context.Context, req *proto.QueryRequest, rsp *proto.QueryResponse) error {
var q model.Query
if len(req.Slug) > 0 {
logger.Infof("Reading post by slug: %v", req.Slug)
q = p.slugIndex.ToQuery(req.Slug)
} else if len(req.Id) > 0 {
logger.Infof("Reading post by id: %v", req.Id)
q = p.idIndex.ToQuery(req.Id)
} else {
q = p.createdIndex.ToQuery(nil)
var limit uint
limit = 20
if req.Limit > 0 {
limit = uint(req.Limit)
}
q.Limit = int64(limit)
q.Offset = req.Offset
logger.Infof("Listing posts, offset: %v, limit: %v", req.Offset, limit)
}
posts := []*proto.Post{
}
err := p.db.List(q, &posts)
if err != nil {
return errors.BadRequest("proto.query.store-read", "Failed to read from store: %v", err.Error())
}
rsp.Posts = posts
return nil
}
( modify proto file , Or modify the code , Just make proto perhaps micro update .)
[[email protected] handler]# micro posts query
{
"posts": [
{
"id": "2",
"title": "Post two",
"slug": "post-two",
"content": "Second saved post",
"created": "1657894638"
},
{
"id": "1",
"title": "Post one",
"slug": "post-one",
"content": "First saved post",
"created": "1657894626"
}
]
}
Delete post
func (p *Posts) Delete(ctx context.Context, req *proto.DeleteRequest, rsp *proto.DeleteResponse) error {
logger.Info("Received Post.Delete request")
return p.db.Delete(model.Equals("id", req.Id))
}
Drop the complete project link :https://github.com/micro/dev/tree/master/blog/v1-posts
边栏推荐
- 7.15模擬賽總結
- 三条线(春季每日一题 59)
- How to choose a desktop multimeter?
- DzzOffice_flowplayer播放器更改
- 探索式软件测试
- Gan online learning notes
- Sword finger offer 32 - I. print binary tree from top to bottom, breadth first search (queue)
- ES (6/7/8/9/10/11) notes
- 基本的unix域协议编程
- After Jay Chou's co branded model, Fang Wenshan brought online shopping to promote the collection of "Hualiu" top-level co branded dolls
猜你喜欢

ES (6/7/8/9/10/11) notes

测试/开发程序员幽默的 “自嘲“?印象流派......

Description of common operators in Halcon 3D

ACL Technology

软件测试零基础测试篇-基本概念
![Guess the size of the number ii[what problem does dynamic planning solve?]](/img/a0/6f94899557df7aff18377411cc10a8.png)
Guess the size of the number ii[what problem does dynamic planning solve?]

micro、M3O微服务系列(一)

MySQL triggers and stored procedures

u盘删除的文件怎么恢复

Dpdk flow filter summary (flow director/ rte_flow)
随机推荐
Dpdk flow filter summary (flow director/ rte_flow)
"Harmonyos" explore harmonyos applications
Clickhouse (04) how to build a Clickhouse cluster
micro、M3O微服务系列(二)
Tools to measure the gap between two distributions: cross entropy and KL divergence
How can the computer recover deleted files? How can I recover deleted data
自动补全(春季每日一题 58)
Problems encountered in deploying edusoho on the Intranet
Halcon 3D create_ pose
28K monthly salary for software testing interview questions for large factories (you can take away the test paper with the permission of the interviewer)
西山居如何用 ONES 打造游戏工业流水线?|ONES 行业实践
DLS-12B/DC220V双位置继电器
晴空一“鹤”排“云”上:以数为翅的中国飞鹤
Sword finger offer 48 The longest substring without repeated characters
Sword finger offer 32 - I. print binary tree from top to bottom, breadth first search (queue)
Description of common operators in Halcon 3D
constrained graphic layout generation via latent optimization
Bluetooth technology | the first Bluetooth Le audio compatible devices will be launched this year, and the endurance of Bluetooth headsets will be improved by leaps and bounds
constrained graphic layout generation via latent optimization
Basic UNIX domain protocol programming