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
目录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
| Operation | HTTP Method | URL |
|---|---|---|
| Create | post | /blog/add |
| Delete | post | /blog/deleteById |
| Update | post | /blog/updateById |
| Query | get | /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
| Operation | HTTP Method | URL |
|---|---|---|
| Create | post | /blog/ |
| Delete | delete | /blog/{id}/ |
| Update | put | /blog/{id}/ |
| Query | get | /blog/ |
| Query | get | /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.
| Category | Description |
|---|---|
| 1xx: Informational | Communication transport protocol-level information. |
| 2xx: Success | Indicates the client's request has been successfully accepted. |
| 3xx: Redirection | Indicates the client must take some additional action to complete its request. |
| 4xx: Client Error | These error status codes point to the client. |
| 5xx: Server Error | The 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.
| Operation | HTTP Method | URL |
|---|---|---|
| Pin | post | /blog/{id}/setTop/ |
| Like | post | /blog/{id}/thumbUp/ |
| Get pinned posts | get | /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 theseservices.
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
- Developing a Blog Project with .NetCore StarBlog - (1) Why Do You Need to Write Your Own Blog?
- Developing a Blog Project with .NetCore StarBlog - (2) Environment Setup and Creating the Project
- Developing a Blog Project with .NetCore StarBlog - (3) Model Design
- Developing a Blog Project with .NetCore StarBlog - (4) Batch Importing markdown Blogs
- Developing a Blog Project with .NetCore StarBlog - (5) Starting to Build the Web Project
- Developing a Blog Project with .NetCore StarBlog - (6) Page Development: Blog Post List
- Developing a Blog Project with .NetCore StarBlog - (7) Page Development: Post Detail Page
- Developing a Blog Project with .NetCore StarBlog - (8) Displaying Category Hierarchy
- Developing a Blog Project with .NetCore StarBlog - (9) Batch Importing Images
- Developing a Blog Project with .NetCore StarBlog - (10) Image Waterfall Layout
- Developing a Blog Project with .NetCore StarBlog - (11) Implementing Visit Statistics
- Developing a Blog Project with .NetCore StarBlog - (12) Dynamic Compilation of Razor Pages
- Developing a Blog Project with .NetCore StarBlog - (13) Adding Friend Links
- Developing a Blog Project with .NetCore StarBlog - (14) Implementing Theme Switching
- Developing a Blog Project with .NetCore StarBlog - (15) Generating Random-Size Images
- Developing a Blog Project with .NetCore StarBlog - (16) Some New Features (Monitoring/Statistics/Configuration/Initialization)
- Developing a Blog Project with .NetCore StarBlog - (17) Automatically Downloading External Images in Posts
- Developing a Blog Project with .NetCore StarBlog - (18) Implementing Local Typora Post Packaging and Upload
- Developing a Blog Project with .NetCore StarBlog - (19) Exploring Markdown Rendering Solutions
- Developing a Blog Project with .NetCore StarBlog - (20) Image Display Optimization
- Developing a Blog Project with .NetCore StarBlog - (21) Starting RESTFul API Development
_EOF_
StarBlog Development Notes (21): Starting RESTFul API Development
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
StarBlog博客开发笔记(11):实现访问统计
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetCore开发博客项目 StarBlog - (3) 模型设计 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入 基于.NetCore开发博客项目 StarBl
2022-06-20 · StarBlog博客开发笔记 · 约 1 分钟
StarBlog博客开发笔记(2):环境准备和创建项目
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 ... 基于.NetCore开发博客项目 StarBlog - 接口返回值包装 基于.NetCore开发博客项目 StarBlog - 上传图片功能 基于.NetCore开发博客项目 StarBlog - 身份认证
2022-04-22 · StarBlog博客开发笔记 · 约 1 分钟
StarBlog博客开发笔记:身份认证功能
身份认证使用JWT,关于AspNetCore的身份认证和JWT可以看看我之前这篇博客 先安装nuget包 dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer 在Services目录下新建一个AuthService类,先留着不写代码,等把准备工作完成了再来。 用户模型 在 StarBlog.Data 项目的 Models
2022-02-25 · StarBlog博客开发笔记 · 约 1 分钟
StarBlog博客开发笔记(25):图片接口与文件上传
前言 上传文件的接口设计有两种风格,一种是整个项目只设置一个接口用来上传,然后其他需要用到文件的地方,都只存一个引用ID;另一种是每个需要文件的地方单独管理各自的文件。这俩各有优劣吧,本项目中选择的是后者的风格,文章图片和照片模块又要能CRUD又要批量导入,还是各自管理文件比较好。 图片接口 说会正题,先介绍一下图片相关接口。 图片列表 首先CRUD是肯定有的,图片列表的分页查看也是有的,不过因为
2023-02-05 · StarBlog博客开发笔记 · 约 1 分钟
讨论
共 0 条加载评论中…