[Day 14] 第一主餐 pt.7-一支API,千万request来相见

(好的我知道标题没押韵很虚,我尽力了)
昨天我们终於处理完Database的东东,并且成功用Django加入我们的资料了
今天我们就要改用API来新增资料啦
废话不多说,咱们累狗

API,爲什麽存在,因爲爱,还是未知的未来

API,应用程序介面
是一种计算介面,它定义多个软件中介之间的互动
以及可以进行的呼叫(call)或请求(request)的种类
如何进行呼叫或发出请求,应使用的资料格式,应遵循的惯例等 -- from wikipedia
讲这麽多,API最简单的概念就是
你今天对API丢了一个东西进去,然後你希望API给你要的东西出来,有时候也可能希望没有
简单来说就是你去扭蛋
你丢了10块、20块、50块或60块进去,你希望这个看起来完全不坚固的东东能给你一个转蛋出来
这个扭蛋机就是一个API
API的输入就是你的蒋公或是你的孙中山
输出就是一颗扭蛋
有没有,你平常日常生活处处可见API啊

那为什麽提到API会用林俊杰的杀手歌词当标题呢
因为这东西,写不好,你家的程序码就会变得非常恐怖
前面的设定参数那些东东我们还可以写的随兴一点
到这里时我们就要严阵以待了
不然你家的code可能就会像本菜鸡前人写的code这样

@api_view(['POST', 'GET', 'PUT'])
@permission_classes([AllowAny])
def user_function(request):

    if request.method == "GET":

        email = request.user.email

        
        ...

        return JsonResponse(data={"data": b_to_json_object(CustomerEmailUserSerializer(c).data), "status": True},
                            status=status.HTTP_200_OK)

    if request.method == "POST":
        try:
            l.info("method {}, user_function, data: {}".format(request.method, request.data))
            data = request.data
        except:
            return JsonResponse(data={"message": "need json format", "status": False},
                                status=status.HTTP_406_NOT_ACCEPTABLE)

        email = data.get('email', None)

        check_account = CustomerEmailUser.objects.filter(email = email)

        if len(check_account) >= 1:
            print(check_account[0].account_type)
            if check_account[0].account_type == 'T':
                ...
            elif check_account[0].account_type == 'F':
                ...

        try:
            validate_email(email)

            if len(email) > 99:
                return JsonResponse(data={"message": "too length", "status": False},
                                    status=status.HTTP_406_NOT_ACCEPTABLE)
        except:
            return JsonResponse(data={"message": "plz using correct email", "status": False},
                                status=status.HTTP_406_NOT_ACCEPTABLE)

        ...


        if email and password or account_type:

            ...

    if request.method == 'PUT':

        ...


而且由於这段是还在实际运行的code,我已经尽量删减很多冗长的code了
但这架构还是恐怖的跟鬼故事一样,你就知道在编写code时保持可读性的重要性了
而至於如何写出一个漂亮的code,最近也刚好拜读了一篇也是本届铁人赛的unit test主题文章
https://ithelp.ithome.com.tw/users/20107429/ironman/3897
内容虽然有些多,但每篇都是实打实的知识点
比我这个画虎烂的菜鸡有料多了,也建议大家可以去看一下这篇铁人主题
真的可以学到平时忽略的东西

好啦回到正题,要想让你的API保持活性以及可读性
想当然尔,写code时的纪律就很重要啦
但毕竟这次主题篇幅有限,我们的aws都还没开工勒
所以要如何在python做unit test,有机会我们会再开个铁人赛跟大家讲解
现在我们会把重点着重在如何完成你人生第一道法式组合餐
不过写的过程我也会提醒一下如何避免写出很丑的code
以免你把其他接手code的人给丑死了

写CODE时的三大规则

好的刚刚前面提到,我们要写一个API,必须要战战兢兢,小心不要把别人丑死了
那要怎麽避免把别人丑死呢
通常我写CODE时会有三大要点(当然基本上一定更多啦,这边就只是讲个基础的方向)

1. 一个function只做一个功能

通常这是写code新手很容易犯的错误
因为为了要赶快让功能上线,看到这个function只有一两行程序码
幸尚宽,何为不可
於是就把功能给加到这个function底下了
於是越加越多,越加越多
结果等到BUG发生时,才发现那个出BUG的code早已被埋在function底下的茫茫大海中
那你找BUG自然就找到天荒地老

2. 同个功能不要重复做

想当年在大学时期时,本菜鸡也很常发生的事情
在某个function写了个好棒棒的功能
然後发现另一个input也要做差不多相同的事,只是参数有点不一样
怎麽办呢
在开一个funciton复制贴上啊,多方便
於是这样开了又开开了又开
一个小小的class直接塞了1000多行程序码
现在看当年那个比菜鸡还菜的coding style,也是不胜唏嘘啊

3. 判断式请别超过3个

这个不废话,上图比较快

看到这种code,100个人内应该会有101个吐血,啊有一个吐两次的

讲到这边,你就会发现一件事情
这三个地雷点,咱们上面的CODE全部都犯过一轮了
所以你就知到本菜鸡当时看CODE多痛苦了
最痛苦的事情是每次要改规格就是牵一发动全身
然後菜鸡的头头每次code reviews又会被挖苦说为什麽CODE这麽蠢
外加多被下一堆规则
真的是有苦难言啊

谨记上述规则,来开工吧

好啦,不管你多麽的怕雷到你的後人
丑媳妇总是要见公婆的
这种东西就是多练就会了
所以我们就赶快练习吧
首先我们先开启views.py,我们大部分的API都在这运作
然後这边就要来介绍Atom的方便功能啦
你可以一边开启models.py,另一边开启views.py
就像这样

我们就可以边写code边比对啦

基於我们这支API只是测试而已,因此我们就把function name取做test_api吧
然後由於他是要透过外部连结call过来的,所以参数要加request
接着就是我们要的功能啦
我们刚刚提到这支API就只要做建立objects,然後储存的简单功能就好
所以我们就照上一篇的方式建立、设定属性,储存
最後再回传HTTP Status Code 200
这个HTTP Status Code是啥呢,因为今天篇幅够长了,咱们下篇讲解
所以根据上述规则,我们就可以写出我们第一支API
因为是第一次写API,所以我会把注解都给标出来,也可以帮助看一下有没有违反前面的三大原则

def test_api(request):

    #建立新的DBTest object
    new_obj = DBTest()
    
    #把新建立的object内的test属性改成"I love Amane Kanata"
    new_obj.test = "I love Amane Kanata"
    
    #储存object
    new_obj.save()
    
    #回传200,这里使用JsonResponse,data记得回传格式为dict
    return JsonResponse(data={'msg':'add object success.'}, status=200)

然後也别忘了前面要再import相关套件

from django.http import JsonResponse #刚刚的JsonResponse套件
from stonks_index.models import DBTest #从models.py import DBTest 物件

好的,views.py的部分就完成了,接下来就是url的部分啦
首先我们先开stonks_root的urls.py
然後改成下列code

from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url

admin.autodiscover()

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^stonks/', include('stonks_index.urls')),
]

这个部分代表着假设我们的url後面开头是stonks的话就到stonks_index的url做後续动作
接着我们进到stonks_url可以发现
他,没有urls.py
怎麽办呢,简单,建立一个就好了嘛
建立完之後加上这段code

from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'test_api/$', views.test_api),
]

这段code代表假设stonks/後面又接着test_api的话就执行views.py内的test_api function
好啦,到此coding部分就完成啦
我们来执行看看,不过执行之前我们先把table内的东西全部砍掉
可是要进去shell也是有点麻烦
那就再加个功能就好啦
我们在views.py再加上下面这段code

def clear_table(request):

    #将table所有data捞出来
    all_obj = DBTest.objects.all()

    #砍掉
    all_obj.delete()

    #回传200,这里使用JsonResponse,data记得回传格式为dict
    return JsonResponse(data={'msg':'clear table success.'}, status=200)

然後我们的stonks_index内的urls.py改成如下

from django.conf.urls import url
from . import views
urlpatterns = [
    url(r'test_api/$', views.test_api),
    url(r'clear_table/$', views.clear_table),
]

都准备好了我们就可以来执行看看啦
我们执行一次runserver,这里就不打详细的指令了
首先先执行http://172.16.15.123:8000/stonks/clear_table/

执行成功,接着执行http://172.16.15.123:8000/stonks/test_api/

执行成功,最後我们再去看一次table资料
执行shell,然後输入from stonks_index.models import DBTest
接着输入DBTest.objects.all()

可以看到我们刚刚加入的data,就代表成功啦

以上就是API的介绍,以及写API时需要注意的事项
下一步我们就会在url request上加点料
以及介绍一个好用的API测试程序
想要知道API还能玩出什麽花样
且待下回分解~


<<:  Day10-119. Pascal's Triangle II

>>:  IT铁人DAY 10-Abstract Factory 抽象工厂

Day.20 从零开始 - 实务需求学SQL_1

今天的主题来透过应用实例复习常用SQL语法,普通的解释相对无聊~所以我们边举例边看过程中可能遇到的...

Day 21 - Android Studio ImageView的基本使用

Day 21 - Android Studio ImageView的基本使用 昨天我们讲到了Edit...

[Day09] Flutter with GetX gallery_saver 照片影片存到相簿

Gallery saver 取得权限的前置作业 iOS Info.plist内新增 NSPhotoL...

微不足道的小事,才真正走进我们心里,累积成了生命中难忘的美好风景。

过去十年,我的人生可以用两个字来形容,很多时候都是在:忙录。(或是瞎忙XD) 从小就被教育要以考高分...

Day 3 - HTAP

上一篇提到了TiDB的特色之一,便是实践了HTAP。那HTAP又是什麽东西? HTAP全名Hybri...