返回顶部
首页 > 资讯 > 后端开发 > GO >golang实现rest server
  • 124
分享到

golang实现rest server

golangrestserver 2023-01-31 07:01:01 124人浏览 泡泡鱼
摘要

背景 用golang对数据库标准操作进行封装,为后面的rest server提供数据库访问层。实现的目标是:能根据rest请求参数自动生成数据库操作语句,提供增、删、改、查、批量写入、事务等必要的数据库操作封装。并可以方便的扩展到多种数

背景

golang数据库标准操作进行封装,为后面的rest server提供数据库访问层。实现的目标是:能根据rest请求参数自动生成数据库操作语句,提供增、删、改、查、批量写入、事务等必要的数据库操作封装。并可以方便的扩展到多种数据库,让所有的数据库操作对于rest server来说表现为一致的访问接口。

一些关键点

  1. 接口设计做到恰到好处,够用且不繁杂。
  2. 函数参数的设计,Go不支持函数重载,如何善用interface{}。
  3. 用map[string]interface{}来处理rest的JSON请求参数,并自动生成相应的sql
  4. 数据库查询结果能方便的转化为json,让rest server返回给用户。

代码解析

按功能模块对核心代码进行说明

IBock.go

数据库标准操作接口定义,根据我的实践经验,以下的接口设计已经能够很好的支持大部分的数据库操作,这些操作包括了根据json参数自动完成的CURD、手写sql支持、批量插入(更新)心及事务操作。
type IBock interface{
    //根据参数,自动完成数据库查询
    Retrieve(params map[string]interface{}, args ...interface{}) map[string]interface{}
    //根据参数,自动完成数据库插入
    Create(params map[string]interface{}, args ...interface{}) map[string]interface{}
    //根据参数,自动完成数据库更新(只支持单条)
    Update(params map[string]interface{}, args ...interface{}) map[string]interface{}
    //根据参数,自动完成数据库删除(只支持单条)
    Delete(params map[string]interface{}, args ...interface{}) map[string]interface{}
    //手写查询sql支持
    QuerySql(sql string, values []interface{}, params map[string]interface{}) map[string]interface{}
    //手写非查询sql支持
    ExecSql(sql string, values []interface{}) map[string]interface{}
    //批量插入或更新
    InsertBatch(tablename string, els []interface{}) map[string]interface{}
    //事务支持
    TransGo(objs map[string]interface{}) map[string]interface{}
}
参数说明
  • params, 对应rest server接收到用户数据,由json对象转换而来。
  • args,这个参数的目标是接收id(信息ID),fields(表字段数组),session(用户session)这三个参数,这样做的初衷是既要统一接口函数形式,又可以在编码时少传入作为点位符的nil
  • values,为sql查询参数化提供的参数列表
  • els,批量插入的每一行数据对象集
  • objs,事务对象集
  • 返回参数为go的映射,很容易转化为json。

Bock.go

接口的具体实现,本文是对Mysql的实现,暂只实现了基本的CURD,项目中会逐步完善。
//我们把操作对象定义在一个表上
type Bock struct {
    Table string
}
//parseArgs函数的功能是解析args参数中包括的可变参数,实现在下面
func (b *Bock) Retrieve(params map[string]interface{}, args ...interface{}) map[string]interface{} {
    //查询时我们一般只关注查询哪些表字段
    _, fields, _ := parseArgs(args)
    //调用具体的查询接口,查询接口将根据输入参数params自动实现sql查询语句,支持多样的查询定义,如:lks(从多个字体查询相同内容),ors(或查询),ins(in查询)等
    return Query(b.Table, params, fields)
}

func (b *Bock) Create(params map[string]interface{}, args ...interface{}) map[string]interface{} {
    //新建接口,一般都会关注用户在session的ID
    _, _, session := parseArgs(args)
    uId := session["userid"].(string)
    params["u_id"] = uId
    //调用具体的插入接口
    return Insert(b.Table, params)
}

func (b *Bock) Update(params map[string]interface{}, args ...interface{}) map[string]interface{} {
    //只支持单个更新,所以ID必须存在
    id, _, _ := parseArgs(args)
    if len(id) == 0 {
        rs := make(map[string]interface{})
        rs["code"] = 301
        rs["err"] = "Id must be input."
        return rs
    }
    return Update(b.Table, params)
}

func (b *Bock) Delete(params map[string]interface{}, args ...interface{}) map[string]interface{} {
    //只支持单个删除,所以ID必须存在
    id, _, _ := parseArgs(args)
    if len(id) == 0 {
        rs := make(map[string]interface{})
        rs["code"] = 301
        rs["err"] = "Id must be input."
        return rs
    }
    return Delete(b.Table, params)
}
parseArgs函数的实现
func parseArgs(args []interface{}) (string, []string, map[string]interface{}) {
    //解析指定的参数
    var id string                                //信息ID
    var fields []string                          //查询字段集
    var session map[string]interface{}           //用户session对象
    for _, vs := range args {
        switch vs.(type) {
        case map[string]interface{}:            //只接收指定类型
            for k, v := range vs.(map[string]interface{}) {
                if k == "id" {
                    id = v.(string)
                }
                if k == "fields" {
                    fields = v.([]string)
                }
                if k == "session" {
                    session = v.(map[string]interface{})
                }
            }
        default:
        }
    }
    return id, fields, session    //返回解析成功的参数
}

Helper.go

数据操作的具体实现,大多是伪代码,项目后续会逐步完善,查询接口最重要,后面会有单独文章进行解析
func Query(tablename string, params map[string]interface{}, fields []string ) map[string]interface{} {
    //调用具体实现的私用函数,接口中分自动和手动两个函数,在私用函数中屏蔽差异内聚功能
    return query(tablename, params, fields, "", nil)
}

func Insert(tablename string, params map[string]interface{}) map[string]interface{} {
    sql := "Insert into " + tablename
    values := make([]interface{},0)
    return execute(sql, values)
}

func Update(tablename string, params map[string]interface{}) map[string]interface{} {
    sql := "Update " + tablename + " set "
    values := make([]interface{},0)
    return execute(sql, values)
}

func Delete(tablename string, params map[string]interface{}) map[string]interface{} {
    sql := "Delete from " + tablename + " where"
    values := make([]interface{},0)
    return execute(sql, values)
}
私用查询函数定义
//五个输入参数,分别适配自动与手动查询
func query(tablename string, params map[string]interface{}, fields []string, sql string, vaules []interface{}) map[string]interface{} {
    if vaules == nil {
        vaules = make([]interface{},0)
    }
    //调用真正的数据库操作函数
    return execQeury("select "+ strings.Join(fields, ",")+" from " + tablename, vaules)
}
非查询类具体操作函数
//因为golang把有结果集的和无结果集的操作是分开的,不象在java或node.js中,可以有高级函数进行统一操作,只能分开。
func execute(sql string, values []interface{}) map[string]interface{}  {
    //返回json对象,以map形式表达
    rs := make(map[string]interface{})
    rs["code"] = 200
    return rs
}
查询类具体操作(已经实现),结果集以json对象封装,存储在map中
func execQeury(sql string, values []interface{}) map[string]interface{}  {
    var configs interface{}
    ...//省略数据配置获取代码,请参照以前的文章
    dao, err := mysql.Open(dialect, dbUser + ":"+dbPass+"@tcp("+dbHost+":"+dbPort+")/"+dbName+"?charset="+dbCharset)
    stmt, err := dao.Prepare(sql)
    rows, err := stmt.Query(values...)

    columns, err := rows.Columns()       //取出字段名称
    vs := make([]mysql.RawBytes, len(columns))
    scans := make([]interface{}, len(columns))

    for i := range vs {                 //预设取值地址
        scans[i] = &vs[i]
    }

    var result []map[string]interface{}
    for rows.Next() {
        _ = rows.Scan(scans...)        //塡入一列值
        each := make(map[string]interface{})

        for i, col := range vs {
            if col != nil {
                each[columns[i]] = string(col)        //增值
            }else{
                each[columns[i]] = nil
            }
        }

        result = append(result, each)
    }
    rs["code"] = 200
    //data, _ := json.Marshal(result)            //这样就能转换为json
    rs["rows"] = result
    return rs
}
数据库的批量操作,在前面的文章中已经用golang实现,只是还未封装,有兴趣的朋友可以看我前面的文章。

bock.go(程序入口)

最终目标的入口将是一个网络服务,提供标准的restful服务,现在只是用来测试,再这说明一下愿景。
    table := Bock.Bock{                    //上体实例
        Table: "role",                     //对role表时行操作
    }
    var params map[string] interface{}     //模拟json参数
    args := make(map[string] interface{})  //其它参数
    db := make([]DB.IBock, 1)              //对接口编程
    db[0] = &table                         //接口指向实例对象,这里可以现时处理多个不同的实例
    fields := []string {"id", "name"}
    args["fields"] = fields
    rs, _ := db[0].Retrieve(params, args)  //在这可以循环处理多个不同的实例,我们最终的目标就是在这接受用户的Http请求,由路由自动分发不同的请求,我们的数据库封装自动生成sql语句完成用户的基本需求。
    fmt.Println(rs)

项目地址

https://GitHub.com/zhoutk/goTools

使用方法

git clone https://github.com/zhoutk/goTools
cd goTools
go get
go run bock.go

go buid bock.go
./bock        

小结

经过多种方案的对比,发现go语言作为网络服务的吞吐率是最棒的,所以有了将以往在其它平台上的经验(node.js,java,python3),用go来实现,期望有惊喜,写代码我是认真的。

您可能感兴趣的文档:

--结束END--

本文标题: golang实现rest server

本文链接: https://lsjlt.com/news/192252.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • golang实现rest server
    背景 用golang对数据库标准操作进行封装,为后面的rest server提供数据库访问层。实现的目标是:能根据rest请求参数自动生成数据库操作语句,提供增、删、改、查、批量写入、事务等必要的数据库操作封装。并可以方便的扩展到多种数...
    99+
    2023-01-31
    golang rest server
  • springmvc如何实现Rest风格
    这篇文章主要介绍了springmvc如何实现Rest风格,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。简介  REST 即 Representational State Tr...
    99+
    2023-05-30
    spring mvc rest
  • Golang简单实现http的server端和client端
    介绍 HTTPS (Secure Hypertext Transfer Protocol)安全超文本传输协议,是一个安全通信通道,它基于HTTP开发用于在客户计算机和服务器之间交换...
    99+
    2024-04-02
  • spring中REST和RESTful怎么实现
    今天小编给大家分享一下spring中REST和RESTful怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。简介RES...
    99+
    2023-06-29
  • 用Python实现CRUD功能REST服
    最近内部需要实现一个新的HTTP REST服务,数据用JSON。打算用Python来做一个原型,用于比较和Java实现方案的具体差异,以前也没有Python实战经验,所以摸索过程如下。 首先定义协议,假定我们要实现一个群组成员管理的服务&#...
    99+
    2023-01-31
    功能 Python CRUD
  • golang rest参数的作用是什么
    在Go语言中,rest参数的作用是接收可变数量的参数。它是一种特殊的函数参数,可以接收任意数量的同类型参数。 rest参数使用三个点...
    99+
    2023-10-22
    golang
  • golang rest参数的用法是什么
    在Golang中,可以使用"…"语法来定义一个函数的可变参数,也称为rest参数。它允许函数接受任意数量的参数。...
    99+
    2024-02-29
    golang
  • SpringBoot与Postman实现REST模拟请求的操作
    前言 Postman是一款Http请求模拟工具.它可以模拟各种Http Request,使用起来十分的方便. 使用背景 利用Spring Boot 快速搭建一个Web应用,利用相同的...
    99+
    2024-04-02
  • Django Rest Framework实现身份认证源码详解
    目录一.Django框架二.身份认证的两种实现方式:三.身份认证源码解析流程一.Django框架 Django确实是一个很强大,用起来很爽的一个框架,在Rest Framework中...
    99+
    2024-04-02
  • spring中REST和RESTful的区别以及基本实现
    目录简介REST概念:RESTful概念:RESTful实现GET, 查询所有用户信息GET, 根据用户ID查询用户信息POST, 添加用户信息PUT, 修改用户信息简介 REST概...
    99+
    2024-04-02
  • golang栈实现
    Golang是一种高效、可扩展和并发性强的编程语言,在互联网行业中被广泛使用和推崇。对于Golang的开发者来说,数据结构和算法是基本功之一,而其中栈(Stack)的实现是必不可少的一部分。在本文中,我们将深入探讨如何在Golang中实现栈...
    99+
    2023-05-16
  • golang实现office
    Golang是一个高性能、分布式、并发的编程语言,它可以用来开发各种类型的应用程序。在企业环境中,很多公司使用Microsoft Office来创建和编辑文档、电子表格、演示文稿等文档。然而,Microsoft Office是商业软件,需要...
    99+
    2023-05-16
  • golang实现hash
    哈希(Hash)指的是将任意长度的二进制串映射为固定长度的二进制串的一种方法,该映射规则就是哈希算法,也称为散列算法。哈希算法经常被用来加密、检验数据完整性以及散列表查找等应用中。Go语言(golang)提供了标准库中的hash包,该包提供...
    99+
    2023-05-16
  • golang http 实现
    Golang 是一种快速、简单、高效和安全的编程语言,非常适合构建分布式系统和网络编程。在 Golang 中,提供了一个内置的 http 包,用于构建基于 HTTP 协议的 Web 应用程序。本文将介绍如何使用 Golang 的 http ...
    99+
    2023-05-21
  • golang实现jwt
    在当今的互联网应用开发中,安全性越来越受到重视。JSON Web Tokens(JWT)已成为大多数Web API设计中的常见身份验证和授权方案之一。JWT是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安...
    99+
    2023-05-22
  • golang stack实现
    Golang是一种相对新的编程语言,它的高效性和并发性使其成为越来越受欢迎的编程语言。 Golang有一个强大的标准库,其中包含了各种数据结构和算法,其中之一就是栈(Stack)。栈是一种数据结构,可以用于在程序中存储和操作数据。它类似于一...
    99+
    2023-05-21
  • jvm 实现 golang
    JVM实现Golang近年来,Golang(也称作Go)已经成为了广泛使用的编程语言之一。Golang具有强大的并发性能和高效的资源利用率,成为了许多大型企业和公司技术栈中的首选语言。但是,作为一门比较年轻的编程语言,Golang在某些方面...
    99+
    2023-05-21
  • golang实现restful
    Golang是一种高效、快速、安全、可靠的编程语言。它拥有轻量级的语法、并发编程能力和丰富的API库,这使得它成为构建高性能、高可用性的应用程序的理想语言。在本篇文章中,我们将介绍如何使用Golang实现RESTful API。什么是RES...
    99+
    2023-05-22
  • golang 实现 mq
    随着互联网的快速发展,越来越多的应用程序需要进行大量的消息传递。在这种情况下,MQ(Message Queue)成为了一种流行的解决方案。很多语言都有对应的MQ实现,本篇文章将介绍如何使用golang实现MQ,并且简单介绍如何使用golan...
    99+
    2023-05-22
  • golang实现stream
    随着数据处理的需求逐渐增加,流处理成为了一种非常重要的处理方式。最近几年,类似Spark Streaming、Fink和Storm等技术的出现,进一步推动了这种处理方式的应用。Go语言本身就有非常出色的并发处理能力,因此越来越多的开发者将目...
    99+
    2023-05-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作