曦远 (DealiAxy)一份私人的文字刊物

StarBlog
返回文章列表折页手记阅读全文
StarBlog博客开发笔记

StarBlog Development Notes (21): Starting RESTFul API Development

Preface My computer broke recently, which also affected the progress of the open-source project. This post has been brewing for a long time. As the first article of the second part of this series (API development), I wanted a good opening. I kept thinking about it and ended up putting it off for ages, so I'll just skip the rambling and start writing~ About RESTFul A lot of related articles online copy-paste the whole history of RESTFul, so I won't repeat that here. Currently there are mainly two HTTP API styles: RPC and RESTFul. An example will make the difference between the two clear. RPC Style These are the create, delete, update, and query

曦远 (DealiAxy)约 29 分钟
目录9 个章节

Preface

My computer broke recently, which also affected the progress of the open-source project.

This post has been brewing for a long time. As the first article of the second part of this series (API development), I wanted a good opening. I kept thinking about it and ended up putting it off for ages, so I'll just skip the rambling and start writing~

About RESTFul

A lot of related articles online copy-paste the whole history of RESTFul, so I won't repeat that here. Currently there are mainly two HTTP API styles: RPC and RESTFul.

An example will make the difference between the two clear.

RPC Style

These are the create, delete, update, and query endpoints respectively

OperationHTTP MethodURL
Createpost/blog/add
Deletepost/blog/deleteById
Updatepost/blog/updateById
Queryget/blog/getAll

You can see the characteristics of the RPC style:

  • Basically just uses the post and get methods to operate the APIs
  • URL naming is like function naming, all verbs, clear at a glance

PS: With RPC, almost every team has its own style. I've seen people make every endpoint a post method, then put all request parameters in json format in the body.

The key issue is that these request parameters aren't even consistent—different developers on the same project write inconsistent request parameter formats, which is really annoying. (Some WeChat APIs are like this too)

RESTFul Style

These are the create, delete, update, and query endpoints respectively

OperationHTTP MethodURL
Createpost/blog/
Deletedelete/blog/{id}/
Updateput/blog/{id}/
Queryget/blog/
Queryget/blog/{id}/

You can see the characteristics of the RESTFul style:

  • Uses various HTTP methods to implement CRUD (there are also methods like patch and head, which I won't go into)
  • URL naming uses nouns, with the resource name as the URL, more consistent
  • Uses get to retrieve resources, making it convenient for the backend, client, gateway, etc. to cache and improve performance

API Return Values

Besides requesting APIs, RESTFul also recommends using different HTTP status codes based on different states when the API returns.

Below are the five categories of status codes defined by HTTP.

CategoryDescription
1xx: InformationalCommunication transport protocol-level information.
2xx: SuccessIndicates the client's request has been successfully accepted.
3xx: RedirectionIndicates the client must take some additional action to complete its request.
4xx: Client ErrorThese error status codes point to the client.
5xx: Server ErrorThe server is responsible for these error status codes.
  • For example, after adding data, return 201 (created)
  • For add, update, and delete endpoints that don't need to return data, return 204 (no content)
  • Not logged in, return 401 (unauthorized)
  • Not found, return 404 (not found)
  • No permission, return 403 (forbidden)

This way it's very clear—you can tell the result just by looking at the status code returned by the API.

In some frontend ajax libraries (such as axios), if the return code is 4xx or 5xx, an exception is thrown, so the request logic can show some prompts based on the error.

Example

Suppose the API return structure is like this

{
    "successful": true,
    "message": "请求成功",
    "data": [{...}, {...}, {...}]
}

The JavaScript code for requesting the API is as follows

axios.get('/blog/')
	.then(res => msg.success(`请求成功,返回信息:${res.data.message}`))
	.catch(res => msg.error(`请求失败,返回信息:${res.data.message}`))

But! Real-world scenarios are complex. There are only 40 standard HTTP status codes, which is nowhere near enough.

So these HTTP status codes can only roughly classify the return values; complex systems still need to define their own set of error codes.

Summary

Each has its pros and cons. RESTFul looks more consistent and elegant, but has limited expressiveness; RPC URL naming looks more casual, but there's also a lot of room to play freely.

Personally I prefer the RESTFul style, so StarBlog uses RESTFul-style APIs. However, this can't satisfy all functional requirements, so I referenced Django's RestFramework and combined RESTFul and RPC a bit.

For example: adding features like pinning and liking on top of blog CRUD.

OperationHTTP MethodURL
Pinpost/blog/{id}/setTop/
Likepost/blog/{id}/thumbUp/
Get pinned postsget/blog/getTop/

You can see this mashup is based on RESTFul, and for features beyond CRUD, it uses the RPC style on the corresponding resource.

setTop / thumbUp / getTop these verbs are also called action in RestFramework, meaning actions performed on a series of resources.

Regarding HTTP methods: for those that modify resources, use the post method; for those that don't modify and only read, use the get method.

API Development Plan

The update order of this series of articles is basically consistent with StarBlog's development order, that is, adding RESTFul APIs on top of the existing MVC-architecture website, for the admin backend (frontend-backend separation) to configure and manage the blog.

Currently I've divided the APIs into these categories

  • auth - authentication and authorization, as the name suggests, I'll go into detail later
  • admin - admin-related, main features include configuration management, visit records, system monitoring, etc.
  • blog - blog-related, the features are crud for posts, categories, images, and other info
  • common - common APIs; besides blog features, StarBlog also provides some small features in API form, such as a line of poetry, a quote, random images, theme switching, etc.
  • test - test APIs, used for some feature testing; access will be disabled in production
  • links - friend link management; this feature is fairly complex, so it's made into a separate category

Later there will be more complex features like friend links added (such as comments), which will be made into separate categories.

PS: When developing the blog frontend earlier, I put most of the functionality in services. Now that I'm developing the APIs, that comes in handy—a lot of the logic is shared, so in the API controller you just need to call these services.

Other Things to Pay Attention To

This article doesn't cover specific implementation; it's just a preface or outline for the RESTFul API development section. API development seems as simple as the four crud operations, but it's actually more complex than you'd imagine.

For example, the get-posts-list API: a blog can have a lot of posts, so it's impossible for one API to return all post information, therefore pagination is needed. At the same time we also want keyword filtering, categories, status filtering, sorting, and other features on the post list;

Only logged-in users can post comments, and only admins can manage posts, so we need to implement authentication and authorization, role management, and other features;

Many people may visit the blog at the same time (or crawlers), so we need to rate-limit the APIs to prevent the program from crashing;

When there are many APIs, swagger becomes too cluttered, so we need to group the APIs, or switch the swagger frontend;

In production we don't want users to see the swagger API docs, so we can hide them or add a lock to swagger;

For frequently accessed resources, we can use server-side caching to improve performance and reduce IO pressure, and use client-side caching to reduce server traffic;

Time-consuming operations (such as batch exporting posts, sending SMS notifications) should be put into an async task queue (or background tasks) to execute;

The various items listed above are only what I considered the blog would need at the time of writing this article; there should actually be many more. All I can say is that the backend waters run deep, and the process of developing this project is also a process of continuous exploration and practice. "No silver bullet"—no technology applies to every scenario; you can only arrive at the best practices for a given scenario through continuous accumulation.

OK, that's it for this article.

Series Articles

_EOF_

StarBlog Development Notes (21): Starting RESTFul API Development

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

StarBlog博客开发笔记(1):项目介绍

前言 OK,我也来造轮子了 博客系统从一开始用WordPress,再到后来用hexo、hugo之类的静态博客生成放github托管,一直在折腾 折腾是为了更好解决问题,最终还是打算自己花时间搞一个好了 本系列文章将记录博客的开发过程~ 后端基于最新的.Net6和Asp.Net Core框架,遵循RESTFul接口规范,前端基于Vue+ElementUI开发,可作为 .Net Core 入门项目学习

2022-04-05 · StarBlog博客开发笔记 · 约 1 分钟

StarBlog博客开发笔记(27):使用JWT保护接口

前言 这是StarBlog系列在2023年的第二篇更新😂 这几个月都在忙,更新变得很不勤快,但是拖着不更新我的心里更慌,很久没写,要开头就变得很难😑 说回正题,之前的文章里,我们已经把博客关键的接口都开发完成了,但还少了一个最关键的「认证授权」,少了这东西,网站就跟筛子一样,谁都可以来添加和删除数据,乱套了~ 关于「认证授权」的知识,会比较复杂,要学习这块的话,建议分几步: 基础概念 AspN

2023-05-03 · StarBlog博客开发笔记 · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…