Go语言GoFly框架快速新增接口/上手写代码

news2024/12/23 22:48:25

拿到一个新框架大家可能无从下手,因为你对框架设计思路、结构不了解,从而产生恐惧,所以我们框架是通过简单可视化界面安装,安装后即可看到效果,然后点击先点点看各个功能,看现有的功能是怎么写的,这个现成功能作为参考,最好再自己写新的功能,下面我们就带大家如何写新的功能。

通过开发文档的必看章节,我猜您已经在您电脑成功安装并成功运行项目了,通过“开发必看”文档,您已经对哦框架有所了解,现在我们教你如何开发新的功能,对应我们前后端分离框架来说,后端写的功能都是提供给各个前端调用的api接口,所以我们往后开发功能都称为新增“接口”。

新增一个模块

我们在app目录下新加一个模块,当你下载新的代码安装后,app目录下只有admin、business、common三个文件夹和controller.go一个文件,其中controller.go是主控制器可以引入app下模块和设置全局路由拦截及请求前处理。我们用增加wxapp(微信应用模块)举例子,开发步骤如下:

第1.新增一个目录

在app下新建一个名称为 wxapp 的目录,这名称就是这个模块的名称,接口请求就是从wxapp开始也就是域名+wxapp/,例如:https://goflys.cn/wxapp

第2.在目录下添加控制器

wxapp 的目录中新建controller.go一个文件,这个就是整个wxapp 模块的控制器,代码如下:

package wxapp

/**
* 引入控制器
* 请把您使用包用 _ "gofly/app/wxapp/XX"导入您编写的包 自动生成路由
* 不是使用则注释掉
 */
import (
    "gofly/utils/gf"
)

// 路由中间件/路由钩子
func RouterHandler(c *gf.GinCtx, IsCtr bool) {
    if IsCtr { //在这里面处理拦截操作
        c.Next()
    }
}

新建好的控制器文件后,要不这个模块添加到app下的controller.go主控制中并且引入模块路由中间件(如果模块不需拦截则可以不引入),代码如下:

package controller

/**
* app路由引入口《引入模块控制器》
*
* 请把您使用包用 _ "gofly/app/xx"导入您编写的包 自动生成路由
* 不需要使用的模块则注释掉 例如home模块暂时用不到就注释掉,这样不占用资源,使用是取消注释即可。
* 路由规则:包路径“business/article” + 包中结构体“Cate”转小写+方法名(首字母转小写_ "gofly/app/business"
* 有控制的模块请在RouterHandler添加模块的路由钩子
 */
import (
    "gofly/app/admin"
    "gofly/app/business"
    _ "gofly/app/common"
    "gofly/app/wxapp" //新增的wxapp模块
    "gofly/utils/gf"
)

// 路由中间件/路由钩子
func RouterHandler(c *gf.GinCtx) {
    business.RouterHandler(c, gf.IsModelPath(c.FullPath(), "business"))
    admin.RouterHandler(c, gf.IsModelPath(c.FullPath(), "admin"))
    wxapp.RouterHandler(c, gf.IsModelPath(c.FullPath(), "wxapp"))//新增的wxapp模块
}

第3.在wxapp目录下创建接口文件夹

我们在wxapp模块创建名称user的用户相关接口类,和用户相关的接口将在user目录下添加,比如user中常见的用户基本操作(登录,获取用户信息)、用户订单等,我们下面从用户操作和用户订单给大家举例。这个类名user也会生成路由路径,到这里路由为:/wxapp/user,加上域名则为:https://goflys.cn/wxapp/user。我们框架会自动根据目录层级生成接口请求路径,这样路由就不用你手动编写,且不会出现路由重复、命名更规则、可以根据请求的接口路径快速定位代码位置方便更新代码。

第4.在user目录下创建接口文件

我们创建index.go来写用户常见操作,创建order.go来写用户订单相关功能,我们通过index.go和order.go两个给大家讲解接口,index,go中比较特殊框架为了减少路由层级框架对index命名的文件,在生成路由是会忽略index这一级生成路由为:/wxapp/user/+接口名称。其他命名路由会添加文件名,例如order.go生成路由为:/wxapp/user/order/+接口名称。index常用在与类名意义相同的功能上,类型本例user类的用户登录、获取用户信息等是和User类名称对应的功能,所以我们把用户登录、获取用户信息等用户操作功能放到index.go中,这样生成路由基于没有index这一层。

创建接口文件后我们在把user类在wxapp模块控制器引入,就是在app/wxapp/controller.go中import一下user,引入类的代码如下:

package wxapp

/**
* 引入控制器
* 请把您使用包用 _ "gofly/app/wxapp/XX"导入您编写的包 自动生成路由
* 不是使用则注释掉
 */
import (
    _ "gofly/app/wxapp/user" //这个就是新引入的 user类
    "gofly/utils/gf"
)

// 路由中间件/路由钩子
func RouterHandler(c *gf.GinCtx, IsCtr bool) {
    if IsCtr { //在这里面处理拦截操作
        c.Next()
    }
}

4.1 新增index.go文件:

示例我只写接口方法,接口业务这里就不详细展开,您自己根据业务编写,index.go示例代码如下:

package user

import "gofly/utils/gf"

// 用户
type Index struct{}

func init() {
    fpath := Index{}
    gf.Register(&fpath, fpath)
}

// 获取用户信息
func (api *Index) GetInfo(c *gf.GinCtx) {
    user_id, _ := c.Get("userID") //当前用户ID
    userdata, err := gf.Model("business_user").Fields("id,businessID,name,nickname,mobile,email,avatar,status,createtime").Where("id", user_id).Find()
    if err != nil {
        gf.Failed().SetMsg("查找用户数据!").Regin(c)
    } else {
        gf.Success().SetMsg("获取用户信息").SetData(userdata).Regin(c)
    }
}

// 用户登录
func (api *Index) Login(c *gf.GinCtx) {
    //更具登录业务写登录功能
    gf.Success().SetMsg("用户登录").Regin(c)
}

到这里我们就看到终端看到GetInfo和Login两个接口注册到路由中了,您可以通过:域名(服务端地址)+/wxapp/user/getInfo请求接口了。例如下图,大家可能疑问为什么GetInfo会生成为GET请求、Login又会是POST请已经为何首字母变小写,这问题请去:接口开发规范 这一节了解。

3aefed12497540b98ec06efd74f1cb93.png

4.2 新增order.go文件:

在user目录下创建order.go文件,package包名是类目录名user个必须规范,order.go基本代码如下:

package user

import "gofly/utils/gf"

// 用户订单
type Order struct{}

func init() {
    fpath := Order{}
    gf.Register(&fpath, fpath)
}

其中代码的结构体type Order struct{} 的Order名称要和order.go文件名一致,并且把首字母变大写。init函数中fpath := Order{} 的Order就是是=结构体名称,每个文件要写成和文件名称一样。

下面在order中添加功能接口,我们就添加一个获取订单列表GetList、获取订单详情GetDetail和修改订单状态UpStatus(取消订单、确认订单)3个接口做演示。代码如下:

package user

import (
    "gofly/utils/gf"
    "gofly/utils/tools/gmap"
)

// 用户订单
type Order struct{}

func init() {
    fpath := Order{}
    gf.Register(&fpath, fpath)
}

// 获取订单列表
func (Order) GetList(c *gf.GinCtx) {
    pageNo := gf.Int(c.DefaultQuery("page", "1"))
    pageSize := gf.Int(c.DefaultQuery("pageSize", "10"))
    //搜索添条件
    param, _ := gf.RequestParam(c)
    whereMap := gmap.New()
    if gf.DbHaseField("business_ordermanage", "businessID") {
        whereMap.Set("businessID", c.GetHeader("Businessid"))
    }
    user, err := gf.ParseTokenGetInfo(c)
    if err != nil {
        gf.Failed().SetMsg("登录失效请重新登录!").SetCode(401).SetData(err).Regin(c)
    }
    whereMap.Set("uid", user.ID)
    if title, ok := param["title"]; ok && title != "" {
        whereMap.Set("title like ?", "%"+gf.String(title)+"%")
    }
    MDB := gf.Model("business_order").Where(whereMap)
    totalCount, _ := MDB.Clone().Count()
    list, err := MDB.Fields("id,uid,title,status,createtime,updatetime").Page(pageNo, pageSize).Order("id desc").Select()
    if err != nil {
        gf.Failed().SetMsg(err.Error()).Regin(c)
    } else {
        gf.Success().SetMsg("获取全部列表").SetData(gf.Map{
            "page":     pageNo,
            "pageSize": pageSize,
            "total":    totalCount,
            "items":    list}).Regin(c)
    }
}

// 获取订单详情
func (Order) GetDetail(c *gf.GinCtx) {
    id := c.DefaultQuery("id", "")
    if id == "" {
        gf.Failed().SetMsg("请传参数订单id").Regin(c)
    } else {
        data, err := gf.Model("business_order").Where("id", id).Fields("id,uid,title,status,createtime,updatetime").Find()
        if err != nil {
            gf.Failed().SetMsg("获取内容失败").SetData(err).Regin(c)
        } else {
            gf.Success().SetMsg("获取订单详情").SetData(data).Regin(c)
        }
    }
}

// 更新订单状态
func (Order) UpStatus(c *gf.GinCtx) {
    param, _ := gf.RequestParam(c)
    res, err := gf.Model("business_order").Where("id", param["id"]).Data(gf.Map{"status": param["status"]}).Update()
    if err != nil {
        gf.Failed().SetMsg("更新失败!").SetData(err).Regin(c)
    } else {
        msg := "更新成功!"
        if res == nil {
            msg = "暂无数据更新"
        }
        gf.Success().SetMsg(msg).SetData(res).Regin(c)
    }
}

我们会在终端看到GetList、GetDetail、UpStatus生成请求路由了,也就是可以调用这些接口,如下图:

a5a6d01683f4469e883ee0e2c76ae2ae.png

我们细心的朋友可能发现,func 的函数前有个括号index和order两个写法不一样,这样我们和大家说明一下,func (Order) GetList(c *gf.GinCtx) {}中(Order)可以写成func (api *Order) GetList(c *gf.GinCtx) {}这种。func (Order)和func (api *Order)两种在我们示例都可以正常运行,写成func (Order)可以减少点代码,如果您写的业务有连锁操作需求再func (api *Order)这样通api去操作结构体内的变量值等操作。所以用不到api是可以省略,当然你留着也没有影响。

到此您就学会了使用框架新增功能了,同样的需要再现有的admin和business模块新增类或者一个接口也是同样操作,您就自己举一反三自己动手试试,反复写几次让自己对框架有深入了解,千万别急躁慢慢来,要自己多去探索,形成自学习惯。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1715581.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《QT实用小工具·六十八》基于QMenu开发的炫酷菜单栏

1、概述 源码放在文章末尾 该项目基于QMenu实现了炫酷的菜单栏效果,包含了如下功能: 1、实现了类似word菜单栏的效果,可以在菜单栏中横向添加不同的菜单 2、鼠标点击菜单可以展开菜单栏,再次点击菜单可以收起菜单栏 3、鼠标点击笑…

基础—SQL—DQL(数据查询语言)基础查询

一、引言 1、介绍: 分类全称描述DQL英文全称:Data Query Language(数据查询语言)主要是学习对数据库表中的记录进行查询的语句 2、讲解 日常的开发中或者对于一个正常的业务系统中,对于查询的操作次数是远远多于数据的增删改的频次。例如…

SFOS2:组件介绍

一、前言 在sailfish os application的开发过程中,几乎是困难重重,因为我暂未找到具有完整性、指导性、易懂性的开发文档,特别是组件的使用,现决定将自己的探究结果记录下来。因此,这篇文章只会具有参考价值&#xff0…

MS Excel: 高亮当前行列 - 保持原有格式不被改变

本文使用条件格式VBA的方法实现高亮当前行列,因为纯VBA似乎会清除原有的高亮格式。效果如下:本文图省事就使用同一种颜色了。 首先最重要的,【选中你期望高亮的单元格区域】,比如可以全选当前sheet的全部区域 然后点击【开始】-【…

关于 Spring 是什么

Spring 是什么 我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的…

松下MINAS A6B系列旋转电机规格书--A系列

一、松下电机型号的识别方法 二、松下标准型电机型号大全 三、松下电机的规格 四、电机外观 五、XA,XB连接器 六、USB连接器 七、EtherCAT用连接器X2A、X2B 八、IO连接器X4 输入输出信号接口 九、编码器连接器 十、模拟监视器用连接器X7 十一、电源连接器以及端子台…

详解 Spark 的运行架构

一、核心组件 1. Driver Spark 驱动器节点,用于执行 Spark 任务中的 main 方法,负责实际代码的执行工作主要负责: 将用户程序转化为作业 (job)在 Executor 之间调度任务 (task)跟踪 Executor 的执行情况通过 UI 展示查询运行情况 2. Exec…

matlab工具使用记录-编辑器和命令行窗口分开还原

工具:matlab2021b 场景:在使用软件的过程中,我们误操作将matlab的编辑器单独出来了。这时候对软件进行各种操作都还原不回去。 matlab中编辑器和命令行窗口分开了如下图所示。 这时候只需要使用快捷键在编辑器窗口按CtrlshiftD,…

【错题集-编程题】dd 爱旋转(模拟)

牛客对应题目链接:dd爱旋转 (nowcoder.com) 一、分析题目 模拟题,但是需要不能直接无脑模拟,要思考⼀下规律。 顺时针旋转 180:行变换 列变换行变换、列变换的顺序颠倒不会有影响行变换的次数是个数相当于不变 二、代码 #includ…

【B站 heima】小兔鲜Vue3 项目学习笔记 Day06

文章目录 购物车本地1. 列表购物车基础数据渲染2. 列表购物车单选功能3. 列表购物车全选功能4. 列表购物车统计列表实现5. 接口-加入购物车6. 接口-删除购物车7. 退出登录-清空购物车数据8. 合并购物车到服务器(重要) 结算1. 路由配置和基础数据渲染2. 地址切换-打开弹框交互实…

【渗透测试】|文件上传

1、安装使用蚁剑 https://blog.csdn.net/weixin_42474304/article/details/116376746 1、登陆dvwa,进入初级文件上传&#xff0c;上传一句话木马文件cmd.php&#xff0c; //cmd.php <?php eval($_POST[ccit]); ?> //eval: 执行命令的函数 //ccit:一句话木马文件的参数…

刷代码随想录有感(83):贪心算法——最大子数组和

题干&#xff1a; 代码&#xff1a; class Solution { public:int maxSubArray(vector<int>& nums) {int res INT_MIN;int count 0;for(int i 0; i < nums.size(); i){count nums[i];if(count > res) res count;if(count < 0)count 0;}return res;} …

解决Android studio 一直提示下载gradle-xxx-all.zip问题

今天用AndroidStdiod打开一个新工程的时候&#xff0c;发现项目一直卡在正在下载gradle-xxx-all.zip的任务上&#xff0c;网络出奇的慢&#xff0c;即使配了VPN也无济于事&#xff0c;于是按照以往经验&#xff1a;将gradle-xxx-all.zip下载到.gradle\gradle\wrapper\dists目录…

2024年3月电子学会青少年软件编程 中小学生Python编程等级考试一级真题解析(选择题)

2024年3月Python编程等级考试一级真题解析 选择题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 1、下列哪个命令&#xff0c;可以将2024转换成2024呢 A、str(2024) B、int(2024) C、float(2024) D、bool(2024) 答案&#xff1a;A 考点分析&…

【Linux】Linux环境基础开发工具_2

文章目录 四、Linux环境基础开发工具2. vimvim的常见模式 未完待续 四、Linux环境基础开发工具 2. vim vim 是Linux下的一款 多模式编辑器 &#xff0c;可以用来写代码&#xff0c;是 vi 的升级版。 此时无法输入&#xff0c;需要切换模式。 如上图&#xff0c;i 就是切换成…

数据库学习笔记1-数据库实验1

文章目录 创建表格的时候出现的一些错误查询所有的表格实验一查询单个表格分块修改大学数据库表格创建大学数据库表格系课程教师课程段授课学生选课注意吐槽 修改大学数据库表格2&#xff08;英文版本&#xff09;abcde 自建项目-在线书店数据库 创建表格的时候出现的一些错误 …

【ONE·Git || 基本用法入门】

总言 主要内容&#xff1a;主要介绍Git中常用的指令。   PS&#xff1a;多人协作与企业开发模型使用&#xff0c;此部分内容不作博文总结。             文章目录 总言1、初识Git1.1、版本控制器1.2、git安装 2、基本操作2.1、Git本地仓库2.1.1、创建Git本地仓库&…

C++【缺省参数|函数重载|引用】

目录 1 缺省参数 1.1 全缺省 1.2 半缺省 注意 1.3 应用 2 函数重载 函数重载的概念 1、参数类型不同 2、参数个数不同 3、参数类型顺序不同 3 引用 3.1 引用概念 3.2 引用特性 3.3 常引用 3.4 使用场景 3.5 传值、传引用效率比较 3.6 引用和指针的区别 1 缺…

RestTemplet 自定义消息转换器总结

在RestTemplet 请求中&#xff0c;请求发送一个 HTTP 请求时&#xff0c;RestTemplet 会根据请求中的内容类型&#xff08;Content-Type&#xff09;选择合适的 HttpMessageConverter 来处理请求体的数据。同样地&#xff0c;当服务器返回一个 HTTP 响应时&#xff0c;RestTemp…

上位机图像处理和嵌入式模块部署(f103 mcu中main入口函数误解)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 学习stm32代码的时候&#xff0c;关于汇编文件&#xff0c;大家一般都会参考官方给出的汇编文件。通常情况下&#xff0c;不会自己去写汇编文件。特…