悠家娱乐|| Linux 中国,构建一个即时消息应用(四):消息
文章图片
在这篇文章中 , 我们将对端点进行编码 , 以创建一条消息并列出它们 , 同时还将编写一个端点以更新参与者上次阅读消息的时间 。
?来源:linux.cn?作者:NicolásParada?译者:XianLeiGao?
(本文字数:7533 , 阅读时长大约:8分钟)
本文是该系列的第四篇 。
第一篇:模式
第二篇:OAuth
第三篇:对话
在这篇文章中 , 我们将对端点进行编码 , 以创建一条消息并列出它们 , 同时还将编写一个端点以更新参与者上次阅读消息的时间 。 首先在main()函数中添加这些路由 。
【悠家娱乐|| Linux 中国,构建一个即时消息应用(四):消息】router.HandleFunc(''POST'',''/api/conversations/:conversationID/messages'',requireJSON(guard(createMessage)))router.HandleFunc(''GET'',''/api/conversations/:conversationID/messages'',guard(getMessages))router.HandleFunc(''POST'',''/api/conversations/:conversationID/read_messages'',guard(readMessages))
消息会进入对话 , 因此端点包含对话ID 。
创建消息
该端点处理对/api/conversations/{conversationID}/messages的POST请求 , 其JSON主体仅包含消息内容 , 并返回新创建的消息 。 它有两个副作用:更新对话last_message_id以及更新参与者messages_read_at 。
funccreateMessage(whttp.ResponseWriter,r*http.Request){varinputstruct{Contentstring`json:''content''`}deferr.Body.Close()iferr:=json.NewDecoder(r.Body).Decode(&input);err!=nil{http.Error(w,err.Error(),http.StatusBadRequest)return}errs:=make(map[string]string)input.Content=removeSpaces(input.Content)ifinput.Content==''''{errs[''content'']=''Messagecontentrequired''}elseiflen([]rune(input.Content))>480{errs[''content'']=''Messagetoolong.480max''}iflen(errs)!=0{respond(w,Errors{errs},http.StatusUnprocessableEntity)return}ctx:=r.Context()authUserID:=ctx.Value(keyAuthUserID).(string)conversationID:=way.Param(ctx,''conversationID'')tx,err:=db.BeginTx(ctx,nil)iferr!=nil{respondError(w,fmt.Errorf(''couldnotbegintx:%v'',err))return}defertx.Rollback()isParticipant,err:=queryParticipantExistance(ctx,tx,authUserID,conversationID)iferr!=nil{respondError(w,fmt.Errorf(''couldnotqueryparticipantexistance:%v'',err))return}if!isParticipant{http.Error(w,''Conversationnotfound'',http.StatusNotFound)return}varmessageMessageiferr:=tx.QueryRowContext(ctx,`INSERTINTOmessages(content,user_id,conversation_id)VALUES($1,$2,$3)RETURNINGid,created_at`,input.Content,authUserID,conversationID).Scan(&message.ID,&message.CreatedAt,);err!=nil{respondError(w,fmt.Errorf(''couldnotinsertmessage:%v'',err))return}if_,err:=tx.ExecContext(ctx,`UPDATEconversationsSETlast_message_id=$1WHEREid=$2`,message.ID,conversationID);err!=nil{respondError(w,fmt.Errorf(''couldnotupdateconversationlastmessageID:%v'',err))return}iferr=tx.Commit();err!=nil{respondError(w,fmt.Errorf(''couldnotcommittxtocreateamessage:%v'',err))return}gofunc(){iferr=updateMessagesReadAt(nil,authUserID,conversationID);err!=nil{log.Printf(''couldnotupdatemessagesreadat:%vn'',err)}}()message.Content=input.Contentmessage.UserID=authUserIDmessage.ConversationID=conversationID//TODO:notifyaboutnewmessage.message.Mine=truerespond(w,message,http.StatusCreated)}
- 薄情娱乐咖|还能登上人生巅峰,贾诩简直就是张绣的“人生导师”,打一手烂牌
- 悠家娱乐|Pro渲染图,前辈泪流满面加速降价,曝光华为Mate40
- 悠家娱乐|前辈即将残忍让路价崩,曝光华为麒麟9000的跑分已经出来
- 忧家娱乐|前辈闻声价崩疯抢模式,曝光华为mate40后置摄像头排布
- 娱乐那些事儿|蓝牙耳机挂脖式好还是无线好?挂脖式性价比蓝牙耳机排名
- 悠家娱乐|前辈提前价崩简直厉害,我们期待的就剩华为Mate40了
- cnBeta|研究人员担心BleedingTooth蓝牙漏洞给Linux系统带来风险
- 悠家娱乐|一加8无奈下跌黯然神伤,骁龙865版一加8T闪亮登场
- 忧家娱乐|用鸡毛掸子伪装,苏联冷战时期“发射器猎人”模式射频信号追踪器
- 忧家娱乐|2017 年抵御了史上最大的 DDoS 攻击,谷歌称