简单 web 服务与客户端开发实战

任务概述

利用 web 客户端调用远端服务是服务开发本实验的重要内容。其中,要点建立 API First 的开发理念,实现前后端分离,使得团队协作变得更有效率

任务目标

  1. 选择合适的 API,实现从接口或资源(领域)建模,到 API 设计的过程
  2. 使用 API 工具,编制 API 描述文件,编译生成服务器、客户端原型
  3. 使用 Github 建立一个组织,通过 API 文档,实现客户端项目与 RESTful 服务项目同步开发
  4. 使用 API 设计工具提供 Mock 服务,两个团队独立测试 API
  5. 使用 travis 测试相关模块

成果展示

项目 github,我们小组选择开发一个极简博客,具有注册、登录、博客查看、评论等功能,前端使用 Vue.js 构建,后端使用 go 开发

设计说明

我在小组中负责数据库操作的封装,即为其它后端的组员提供可以直接操作数据库的接口,代码集中在db.go中,经过与组员的沟通,确定需要实现的接口有:

  • PutArticles(articles []model.Article)将博客保存到数据库
  • PutUsers(users []model.User)将用户保存到数据库
  • GetArticles(id int64, page int64) []model.Article由博客id获取博客内容
  • GetUser(username string) model.User由用户id获取用户信息

选择使用 mongoDB 进行数据的存储,因为其可以为 WEB 应用提供可扩展的高性能数据存储

1.封装数据库基本操作

引入通过 go 语言操作 mongoDB 的包 mgo

import (
	...
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
)

初始化数据库,获取连接数据库需要的mgo.Session

var globalS *mgo.Session
func Init() {
	dialInfo := &mgo.DialInfo{
		Addrs:    []string{host},
		Source:   dbsource,
		Username: username,
		Password: password,
	}
	s, err := mgo.DialWithInfo(dialInfo)
	if err != nil {
		log.Fatalln("create session error ", err)
	}
	globalS = s
}

对将要用到的插入、查询等数据库操作进行封装,包括连接数据库connect以及对数据库进行操作两步

func connect(db, collection string) (*mgo.Session, *mgo.Collection) {
	mgoSess := globalS.Copy()
	mgoCollec := mgoSess.DB(db).C(collection)
	return mgoSess, mgoCollec
}

func Insert(db, collection string, docs ...interface{}) error {
	ms, mc := connect(db, collection)
	defer ms.Close()
	return mc.Insert(docs...)
}

func Find(db, collection string, query, selector, result interface{}) error {
	ms, mc := connect(db, collection)
	defer ms.Close()
	return mc.Find(query).Select(selector).One(result)
}

func FindAll(db, collection string, query, selector, result interface{}) error {
	ms, mc := connect(db, collection)
	defer ms.Close()
	return mc.Find(query).Select(selector).All(result)
}

2.实现接口

因为 mongoDB 使用需要,首先在各个model_xx.go中的变量加入bson变量名,然后通过调用我们封装好的基本操作实现各个需要的接口,以PutArticles为例,只需要对传入的Article数据循环调用Insert即可

// PutArticles : put articles to database
func PutArticles(articles []model.Article) error {
	for i := 0; i < len(articles); i++ {
		err := Insert(dbsource, Atccollection, articles[i])
		if err != nil {
			return err
		}
	}
}

// PutUsers : put users to database
func PutUsers(users []model.User) error {
	for i := 0; i < len(articles); i++ {
		err := Insert(dbsource, Usrcollection, users[i])
		if err != nil {
			return err
		}
	}
}

// GetArticles : get articles by id from database
// if id == -1 ,find all articles and only return 'page' articles
func GetArticles(id int64, page int64) []model.Article {
	var articles []model.Article
	if id == -1 {
		err := FindAll(dbsource, Atccollection, nil, nil, &articles)
		if err != nil {
			log.Fatal(err)
		}
		if len(articles) > 5
			articles = articles[:5]
	}
	else {
		err := Find(dbsource, Atccollection, bson.M{"id": id}, nil, &articles)
		if err != nil {
			log.Fatal(err)
		}
	}
	return articles
}

// GetUser : get users by username from database
func GetUser(username string) model.User {
	var result model.User
	err := Find(dbsource, Usrcollection, bson.M{"username": username}, nil, &result)
	if err != nil {
		log.Fatal(err)
	}
	return result
}

任务总结

本次项目虽然实现的功能比较简单,但却是一个前后端兼备的项目。一个具有一定规模的项目经过系统的分割后成功由大家配合完成,让我收获了一次宝贵的前后端分离来开发软件的经验,也学习到了通过 API 文档,实现客户端与 RESTful 服务器端同步开发的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值