rest api如何创建

Dockerizing my first REST API written with Go

Docker化我用Go编写的第一个REST API

This is my second post about Go where I share my experience with learning it. This time, we will create a REST API on top of a Postgres database and we will dockerize it to run within a Docker container.

Ť他是我对去哪儿我分享我的学习这方面的经验的第二个职位。 这次,我们将在Postgres数据库之上创建一个REST API,并将其进行泊坞化以在Docker容器中运行。

目标 (The Goal)

Through this post, we will start by creating an Event management API system, with seven endpoints, covering all sorts of basic activities involved like creating, listing, rescheduling, updating, canceling, and deleting events. Then, we take care of the necessary configuration in order to dockerize it.

通过这篇文章,我们将开始创建一个具有七个端点的事件管理API系统,涵盖所有涉及创建,列出,重新安排,更新,取消和删除事件的基本活动。 然后,我们将进行必要的配置,以便对其进行泊坞化。

先决条件: (Prerequisites:)

Same as my first post, this one is accessible for beginners and I’m assuming that you have basic knowledge with SQL or PostgreSQL database, REST APIs and, of course, Docker !

与我的第一篇文章相同,该文章可供初学者使用,并且我假设您具有SQL或PostgreSQL数据库,REST API以及Docker的基本知识!

If it’s not the case, I encourage you to check these learning resources first :

如果不是这种情况,我建议您先检查以下学习资源:

REST应用程序: (The REST application:)

From this point on, I will assume that you have installed all necessary tools on your computer.

从现在开始,我将假定您已经在计算机上安装了所有必需的工具。

So, Let’s begin !

所以,让我们开始吧!

项目结构: (Project structure:)

Let’s start by creating the structure of our project. Setup a new directory for our project, let’s name it events-apiand change the working directory.

让我们从创建项目的结构开始。 为我们的项目设置一个新目录,我们将其命名为events-api并更改工作目录。

> mkdir events-api> cd events-api

Now, we need to initialize a new Go module, to manage the dependencies of the project.

现在,我们需要初始化一个新的Go模块,以管理项目的依赖关系。

You can choose any module path you want, even if it doesn’t use the naming convention “github.com/<username>/<reponame>”.

您可以选择所需的任何模块路径,即使它不使用命名约定“ github.com/ <用户名> / <reponame> ”。

We are all set to start coding our application. But before doing that, let’s divide our project into small components.

我们都准备开始对我们的应用程序进行编码。 但是在此之前,让我们将项目分为几个小部分。

Basically, our API requires some route handlers to handle the HTTP requests, a domain layer that represents our events and a persistence layer that helps us interact with the database.

基本上,我们的API需要一些路由处理程序来处理HTTP请求,代表事件的域层和帮助我们与数据库进行交互的持久层。

So, our solution should like the following by the end of this post:

因此,在本文结尾处,我们的解决方案应如下所示:

.├── bin/├── errors/│   └── errors.go├── handlers/│   └── handlers.go├── objects│   ├── event.go│   └── requests.go├── store│   ├── postgres.go│   └── store.go├── .gitignore├── docker-compose.yml├── Dockerfile├── go.mod├── LICENSE├── README.md├── main.go├── main_test.go└── server.go

Now, we have 4 sub-packages, a directory for binaries, and our root package. Obviously, bin/ will be git ignored.

现在,我们有4个子软件包,一个二进制文件目录以及我们的根软件包。 显然, bin/将被忽略。

  1. The errorspackage will contain all the errors encountered while processing any request.

    errors包将包含处理任何请求时遇到的所有错误。

  2. The handlerpackage is straightforward, it will contain the code for all API route handlers, which will process the request.

    handler包很简单,它将包含所有API路由处理程序的代码,这些代码将处理请求。

  3. The objects package will define our Event’s object along with some other objects.

    objects包将定义我们Event的对象以及其他一些对象。

  4. The storepackage will have our database interaction code. You can see we have 2 files in the package store, store.go defines the interface of all the methods required for interacting with the database or any other storage unit, we would like to use, link an in-memory implementation or a Redis implementation. And hence, postgres.go will implement the store interface.

    store包将具有我们的数据库交互代码。 您可以看到包store有2个文件, store.go定义了我们想使用的,与数据库或任何其他存储单元交互所需的所有方法的接口,并链接了内存中的实现或Redis的实现。 。 因此, postgres.go将实现store接口。

Also, we have 2 files in the root directory, main.go and server.go. The first one will be the entry point of our project and hence, will have the main() function, which will invoke the server runner implemented in the other one. The second one, will create a server and routing handler for application endpoints.

此外,我们在根目录中有2个文件main.goserver.go 。 第一个将是我们项目的入口点,因此将具有main()函数,该函数将调用在另一个中实现的服务器运行程序。 第二个将为应用程序端点创建服务器和路由处理程序。

As you might guess, the Dockerfile and docker-compose.yml will be used to dockerize our API, discussed later in the next section.

您可能会猜到,将使用DockerfileDockerfile docker-compose.yml来对我们的API进行Docker化,这将在下一部分中进行讨论。

错误处理 (Error handling)

You might not be expecting this, but we’re going to start by adding some tools to our arsenal. We’re going to create some error objects that we’re going to use later in our application. Basically, the error object is a readable message with an HTTP status code.

您可能没想到这一点,但我们首先要向我们的军械库添加一些工具。 我们将创建一些错误对象,稍后将在我们的应用程序中使用它们。 基本上,错误对象是带有HTTP状态代码的可读消息。

./errors/errors.go
./errors/errors.go

API规范 (The API Specification)

As we discussed in the ‘The Goal’ section, the idea is simple so is the specification :

正如我们在“目标”部分中讨论的那样,想法很简单,规范也很简单:

……an Event management API system, with seven endpoints……like creating, listing/getting, rescheduling, updating, canceling, and deleting events.

……具有七个端点的事件管理API系统 …… 例如 创建 列出/获取 重新安排 更新 取消 删除 事件。

The first thing we’re going to do is to create the Eventobject.

我们要做的第一件事是创建Event对象。

./objects/event.go
./objects/event.go

For now, please ignore the gorm tags in Id and Slot fields, we will discuss them in the next sections.

现在,请忽略IdSlot字段中的gorm标签,我们将在下一部分中讨论它们。

The next thing we’re going to do is to create the first version of the handlerobject that implements the IEventHandlerinterface.

我们要做的下一件事是创建实现IEventHandler接口的handler对象的第一个版本。

./handlers/handlers.go — v1
./handlers/handlers.go —第1版

店铺实施 (Store implementation)

Before going through the implementation of the IEventHandler, we will need to have a store layer first. So, let’s create an IEventStore interface with Postgres implementation. Each method in this interface will take the execution Context and a request object.

在执行IEventHandler ,我们需要首先具有一个存储层。 因此,让我们使用Postgres实现创建一个IEventStore接口。 该接口中的每个方法都将包含执行上下文和一个请求对象。

So let’s have a look into the request/response objects that we’re going to use in the IEventStore.

因此,让我们看一下我们将在IEventStore使用的请求/响应对象

./objects/requests.go
./objects/requests.go

Now, let’s define the IEventStore.

现在,让我们定义IEventStore

./store/store.go
./store/store.go

As you can see, we’ve a helper method GenerateUniqueId that creates a time based sortable unique id to a precision of up to a fraction of NanoSeconds, we will use this method to set the Id of the event.

如您所见,我们有一个辅助方法GenerateUniqueId ,它创建一个基于时间的可排序唯一ID,其精度最高可达NanoSeconds的一小部分,我们将使用此方法来设置事件的ID。

Now, let’s implement the store interface for Postgres database. For this we will be using GORM — ORM library for Golang, with it’s Postgres driver, so let’s install our first dependency.

现在,让我们实现Postgres数据库的存储接口。 为此,我们将使用GORM —用于Golang的ORM库,以及Postgres驱动程序,因此让我们安装第一个依赖项。

> go get gorm.io/gorm> go get gorm.io/driver/postgres

Now, in the below file, we will implement the interface IEventStore over a struct pg which have a *gorm.DB connection pool.

现在,在下面的文件中,我们将实现接口IEventStore在结构pg其中有一个*gorm.DB连接池。

Also, we have a NewPostgresEventStore constructor that takes the Postgres connection string, sets up the GORM connection pool, with a logger attached to it, that will logs all the queries executed.And returns the PostgreSQL implementation of IEventStore instead of the pg struct. It is the best way to abstract the logic behind the interface, so that only the store is exposed.

另外,我们有一个NewPostgresEventStore构造函数,它采用Postgres连接字符串,建立GORM连接池,并附加一个记录器,该记录器将记录所有执行的查询,并返回IEventStore的PostgreSQL实现而不是pg结构。 这是抽象接口背后逻辑的最佳方法,以便仅公开存储。

Earlier, we had seen that the Id field has a gorm tag specifying primary key, which instructs GORM that ourId field is the primary key in our Events schema. And the Slot field has a gorm:"embedded" tag specifying that the StartTime and EndTime fields of the TimeSlot object should be directly used as the fields of Events schema in the database.

之前,我们看到Id字段具有指定primary keygorm标记,该标记指示GORM我们的Id字段是Events架构中的主键。 而Slot领域有gorm:"embedded"标签,指定的StartTimeEndTime的领域TimeSlot对象应直接使用的领域Events的模式在数据库中。

./store/postgres.go
./store/postgres.go

pg —方法 (pg — Methods)

In Get method:

Get方法中:

p.db.WithContext(ctx).Take(evt, “id = ?”, in.ID).Error

This statement extract the event with the provided identifier inin.ID and map it to the provided object evt. And returns a custom-defined error ErrEventNotFound, defined in the errors package, see the import. (It will be discussed in the next section)

该语句提取in.ID具有提供的标识符的事件,并将其映射到提供的对象evt 。 并返回errors包中定义的自定义错误ErrEventNotFound ,请参阅导入。 (将在下一节中讨论)

In the List method, we have created a custom query using Where and Limit clause and Find all the matching Events mapped in list variable.

List方法中,我们使用WhereLimit子句创建了一个自定义查询,并Find了映射到list变量中的所有匹配事件。

Create method is pretty straightforward, it takes the pre-filled events object and adds it’s entry in the database with CreatedOn set to current time using the database’s NowFunc.

Create方法非常简单,它采用预填充的事件对象,并使用数据库的NowFunc将其条目添加到数据库中,并且CreatedOn设置为当前时间。

UpdateDetails updates the general detail fields specified in Select using the Id field specified in the object, along with the UpdatedOn field, being set to the current time.Similarly, Cancel and Reschedule will update the Event object accordingly.

UpdateDetails使用对象中指定的Id字段更新Select指定的常规详细信息字段,并将UpdatedOn字段设置为当前时间。类似地, CancelReschedule将相应地更新Event对象。

Delete will also work, similar to that of Update the only difference is it will remove the entry from the database, using the Id field.

Delete也将起作用,与Update类似,唯一的区别是它将使用Id字段从数据库中删除条目。

服务器和路由 (Server and Routes)

Now, let’s set up our main server and register all its routes. Of course, before that, we will have to add our next dependency gorilla/mux.

现在,让我们设置主服务器并注册其所有路由。 当然,在此之前,我们将必须添加下一个依赖项gorilla/mux

Let’s check this.

让我们检查一下。

./server.go
./server.go

The Run function creates a mux router with /api/v1/ path prefix defining the version of our API, so that in the future if we want to upgrade the version, we can do it directly from here, instead of changing it everywhere.

Run函数会使用/api/v1/路径前缀创建一个定义了API版本的多路复用器路由器,以便将来如果要升级版本,可以直接在此处进行操作,而无需在任何地方进行更改。

Also, we have created a new store using the constructor in store/postgres.go and a new handler from the constructor in handlers/handlers.go. And then all the routes for the methods in IEventHandler are registered in the function RegisterAllRoutes.

另外,我们使用store/postgres.go的构造函数创建了一个新商店,并使用handlers/handlers.go的构造函数创建了一个新处理handlers/handlers.go 。 然后,将IEventHandler中方法的所有路由都注册到功能RegisterAllRoutes

./main.go
./main.go

The main.go defines the arguments and environment variables required for our project, the Postgres connection string conn and the port over which the server will be running port, which will eventually be passed to the runner Run(args Args) error in server.go.

main.go定义了我们项目所需的参数和环境变量,Postgres连接字符串conn以及服务器将在其上运行的port ,该port最终将传递给server.go中的server.go Run(args Args) error

Now, let’s get back to the Handler implementation part. Each of the methods of IEventHandler performs a set of simple operations involving at most 4 to 5 steps:

现在,让我们回到Handler实现部分。 IEventHandler每个方法IEventHandler执行一组简单的操作,最多包含4到5个步骤:

  1. Extract data from the request body or query parameters
    从请求正文或查询参数中提取数据
  2. Validate the request objects.
    验证请求对象。
  3. Check if the event exists in case of an update or a delete.
    如果更新或删除,请检查事件是否存在。
  4. Final database store call regarding the method.
    有关该方法的最终数据库存储调用。
  5. And at last returning the response.
    最后返回响应。

In order to achieve this, we’re going to need some helpers functions to validate the requests, and write responses.

为了实现这一点,我们将需要一些辅助函数来验证请求并编写响应。

./handlers/helpers.go
./handlers/helpers.go

Thus, completing our API implementation.

至此,完成了我们的API实现。

./handlers/handlers.go
./handlers/handlers.go

测试中 (Testing)

We will be using the default Golang HTTP testing packagenet/http/httptest.

我们将使用默认的Golang HTTP测试包net/http/httptest.

For a matter of readability and considering that most tests are similar. We’re going to focus on the most important ones. But feel free to look for the complete file in my Github repository.

出于可读性考虑,并考虑到大多数测试是相似的。 我们将重点放在最重要的方面。 但是,请随时在我的Github存储库中查找完整的文件。

./handlers_test.go
./handlers_test.go

As you can see, we have a set of test cases with different possibilities, a setup function to return our new http.Request and we use httptest.NewRecorder()to execute it in our API code. You can try to run test by yourself with an active Postgres instance.

如您所见,我们有一组具有不同可能性的测试用例,一个设置函数来返回新的http.Request并使用httptest.NewRecorder()在我们的API代码中执行它。 您可以尝试使用活动的Postgres实例自行运行测试。

Docker化 (Dockerization)

Before we start, let’s first answer, why Docker instead of setting up Postgres and Golang on our machine and start using & testing our application? Well, the question itself has the answer, for anyone to use or try our API, they will have to set up their machine accordingly, which might result in some or any configuration problem or any setup issue. Therefore, to avoid such problems Docker comes into play.

在开始之前,让我们首先回答一下,为什么Docker而不是在我们的机器上设置Postgres和Golang并开始使用和测试我们的应用程序? 好吧,问题本身就是答案,任何人使用或尝试我们的API都必须相应地设置计算机,这可能会导致某些或任何配置问题或任何设置问题。 因此,为避免此类问题,Docker发挥了作用。

Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and deploy it as one package.

Docker是一种工具,旨在使使用容器更轻松地创建,部署和运行应用程序。 容器使开发人员可以将应用程序与所需的所有部分(如库和其他依赖项)打包在一起,并将其作为一个包进行部署。

Docker文件 (Dockerfile)

A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble the deployment. So, let’s dive into the Dockerfile for our API deployment.

Dockerfile是一个文本文档,其中包含用户可以在命令行上调用以组合部署的所有命令。 因此,让我们深入了解我们的API部署的Dockerfile。

./Dockerfile
./Dockerfile
  1. Each Dockerfile starts with some base image, and as we need Golang for our API, so we are starting with golang:alpine image and naming it with an alias: builder (Line: 1-2)

    每个Dockerfile均以一些基本映像开头,并且由于我们需要Golang作为API,因此我们从golang:alpine映像开始,并使用别名: builder命名(第1-2行)

  2. To set any environment variable in Dockerfile we use ENV name=value syntax. And hence, enabling the Go modules in our image. (Line: 4–5)

    要在Dockerfile中设置任何环境变量,我们使用ENV name=value语法。 因此,在我们的映像中启用Go模块。 (第4-5行)

  3. Now, as golang:alpine image doesn’t come with git installed, and we need git to download our dependencies. So, we are including git in the image, using RUN apk update && apk add — no-cache git (RUN command is used to run any command in the terminal in our image). (Line: 7–8)

    现在,由于golang:alpine映像未安装git ,因此我们需要git来下载依赖项。 因此,我们在图像中包括git ,使用RUN apk update && apk add — no-cache git ( RUN命令用于在图像终端中运行任何命令)。 (第7-8行)

  4. Changing the current working directory to /app directory in the image. (Line: 10–11)

    在映像中将当前工作目录更改为/app目录。 (第10-11行)

  5. To avoid downloading dependencies every time we build our image. Here, we are caching all the dependencies by first copying go.mod and go.sum files and downloading them, to be used every time we build the image if the dependencies are not changed. (Line 13–24)
    为了避免每次我们构建映像时都下载依赖项。 在这里,我们首先通过复制go.mod和go.sum文件并下载它们来缓存所有依赖项,以便在不更改依赖项的情况下每次构建映像时使用。 (第13-24行)
  6. And now, copying our complete source code. (Line 26–27)
    现在,复制我们完整的源代码。 (第26–27行)
  7. Creating the binary for our API using the Go build command. Note: we have disabled the CGO integration using CGO_ENABLED flag for the cross-system compilation and it is also a common best practice. Binary will be created in ./bin/ directory as the main file. (Line 29–33)

    使用Go build命令为我们的API创建二进制文件。 注意:我们已使用CGO_ENABLED标志为跨系统编译禁用了CGO集成,这也是常见的最佳实践。 二进制文件将在./bin/目录中创建main文件。 (第29–33行)

  8. To create a small image size we are using docker multi-stage build, which involves starting a new image from scratch (an explicitly empty image) and just copying our binary into it from the builder image tag specified on line 2.

    为了创建较小的映像,我们使用docker多阶段构建,它涉及scratch开始创建新映像(一个明显为空的映像),然后从第2行中指定的生成builder映像标签将二进制文件复制到该映像中。

  9. And executing it using theCMD command.

    并使用CMD命令执行它。

Now, we have our Docker image ready but our image needs Postgres database service, so let’s create a composure file for our deployment.

现在,我们已经准备好Docker映像,但是我们的映像需要Postgres数据库服务,因此让我们为部署创建一个镇静文件。

docker-compose.yml (docker-compose.yml)

Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, we can use a YAML file (default name of the file is docker-compose.yml) to configure our application’s services. Then, with a single command, you create and start all the services from your configuration.

Docker Compose是用于定义和运行多容器Docker应用程序的工具。 借助Compose,我们可以使用YAML文件(该文件的默认名称为docker-compose.yml )来配置应用程序的服务。 然后,使用一个命令,就可以从配置中创建并启动所有服务。

So, let’s start with our compose file.

因此,让我们从撰写文件开始。

  1. Specify the docker-compose version. (Line 1)
    指定docker-compose版本。 (第1行)
  2. Our deployment requires two services, and hence, our file is divided into two services, one named as app and the other as db (Line 3, 5, and 21)

    我们的部署需要两项服务,因此,我们的文件分为两项services ,一项名为app ,另一项名为db (第3、5和21行)

  3. app service starts with naming its container to events_api (Line 6), followed by using our current directory to find the build image, which will eventually use our Dockerfile (Line 7).

    app服务首先将其容器命名为events_api (第6行),然后使用当前目录查找构建映像,该映像最终将使用我们的Dockerfile (第7行)。

  4. Now, we are exposing port 8080 from our service to our local machine in lines 8 and 9, where the syntax for specifying ports is HOST:CONTAINER

    现在,我们在第8行和第9行中将服务中的端口8080公开到本地计算机,其中用于指定端口的语法为HOST:CONTAINER

  5. We are setting a restart policy for our API on any failure in line: 10.
    我们正在针对以下任何失败的API设置重启策略:10。
  6. Setting up the environments: PORT and DB_CONN as required in our main.go Note: that instead of the IP for our Postgres instance we are using the name of the Postgres service, the service name is already mapped with the service’s container IP in Docker. (Line 11–13)

    建立环境: PORTDB_CONN在我们需要main.go注意:而不是IP为我们的Postgres的实例中,我们使用的是Postgres的服务的名称,服务名称已被映射在码头工人服务的集装箱IP。 (第11-13行)

  7. Though not necessary but we are linking a volume space for our API in lines 14–15. It is one of the best practices.
    尽管不是必需的,但是我们在第14-15行中为API链接了一个卷空间。 这是最佳做法之一。
  8. As our API service depends on and is linked with our Postgres service, we are specifying the connection in lines 16–19.
    由于我们的API服务依赖于Postgres服务并与之链接,因此我们在第16-19行中指定连接。
  9. Moving to our second service configurations. We will be using the default postgres image (it will be automatically downloaded if you don’t have it in your system) — Line 21–22

    转到我们的第二个服务配置。 我们将使用默认的postgres图像(如果您的系统中没有它,它将自动下载)—第21–22行

  10. Line 23 specifies our database container name events-db

    第23行指定我们的数据库容器名称events-db

  11. Line 24 exposes 5432 port to our host machine so that we can check the database.
    第24行将5432端口暴露给我们的主机,以便我们可以检查数据库。
  12. And lines from 26 to 31 sets the environment variable for database configuration. TZ and PGTZ are the default time zone setting variables for our database, which is set to UTC.

    从26到31的行设置用于数据库配置的环境变量。 TZ and PGTZ是我们数据库的默认时区设置变量,设置为UTC。

Now, our API is completely ready to be built and tested. You can build the image using the command in our root directory i.e. ./events-api:

现在,我们的API已完全准备好进行构建和测试。 您可以使用我们的根目录(即./events-api的命令来构建映像:

docker-compose up

Note: that the up sub-command will automatically build the image if it is not present, & if does not specify the build flag instead docker-compose up --build

注意: up 子命令将自动构建映像(如果不存在),并且&如果未指定build标志,而是 docker-compose up --build

测试应用程序: (Testing the application:)

Now that we have everything set up, let’s hit our list events endpoint to have an empty result: http://localhost:8080/api/v1/events.

现在我们已经完成了所有设置,让我们点击列表事件端点以得到空结果: http:// localhost:8080 / api / v1 / events 。

Not very convincing. Right? Let’s try the following requests :

不是很令人信服。 对? 让我们尝试以下请求:

Also, we have our Postgres instance running at this stage, so we can also run our test file. Run the following command to test our package:

另外,我们在此阶段运行Postgres实例,因此我们也可以运行测试文件。 运行以下命令以测试我们的软件包:

go test -v server.go main.go handlers_test.go -covermode=count  -coverprofile=./bin/coverage.out

结论 (Conclusion)

This blog completes the journey of creating and dockerizing any API system with a concrete example and the complete step-by-step instructions, using Gorilla Mux and GORM with Postgres, along with Docker to set up and run our service.

该博客通过使用Gorilla Mux和GORM与Postgres以及Docker一起设置和运行我们的服务,通过一个具体的示例和完整的分步说明,完成了创建和码头化任何API系统的过程。

Thank you for your time. Feel free to leave a reply or to check the source code on my Github.

感谢您的时间。 随时发表回复或查看我的Github上的源代码。

翻译自: https://medium.com/codeshake/my-baby-steps-with-go-creating-and-dockerizing-a-rest-api-80522bc478cf

rest api如何创建

http://www.taodudu.cc/news/show-2480718.html

相关文章:

  • 在nginx中编写html,码头不会在nginx html根目录中创建文件夹
  • 张张催人泪下 图说“工人阶级”的心酸谋生路
  • docker 的初步接触
  • docker学习(二)docker入门
  • 在配置DNS后服务器启动失败问题的排查
  • Docker安装、开发环境配置及项目搭建(二,Docker桌面应用)
  • docker安装时报服务失败,因为控制进程退出并带有错误代码
  • 桌面版docker安装搭建
  • 关于win7 环境下安装docker容器的步骤 以及过程中的问题解决
  • 51
  • docker技术简介
  • Docker 极简入门指南
  • 狂热分子——码头工人的哲学沉思录
  • 纽约时报 | 一个机器人导致六名工人失业,工资下降四分之三
  • Docker码头工人之将爬虫放入docker运行
  • “码头工人”的Docker进阶之路:从轻装上路到网络、存储和安全
  • postgresql和es_Apache的气流和PostgreSQL与码头工人和码头工人组成
  • 码头tsb_码头工人及其内部
  • getch()函数怎么用
  • getch()函数
  • 第四章软件项目进度管理
  • RocketMQ消费进度管理
  • 十大项目管理知识-进度管理
  • 项目进度管理(一)
  • 十大管理之项目进度管理知识点
  • 小米手机获取root权限最常见问题
  • 小米手机ROOT操作
  • 小米手机Root的过程及解决Unable to get view server version from device问题
  • 小米android6.01 root,小米6 root教程_小米6获取root权限的方法
  • 小米手机root步骤

rest api如何创建_我的宝宝走了一步,创建了一个REST API并进行了码头化相关推荐

  1. apple id无法创建_我如何为我的Apple收藏夹创建网站

    apple id无法创建 A while ago I started an Apple collection. I've been following Apple hardware (and its ...

  2. python调用api应用接口_第三方免费快递物流查询接口平台(快递鸟)api接口调用...

    随着网购的发展,快递业也随之壮大.快递查询接口对接的需求量也越来越大,下面是对免费快递接口做的整理,并附上调用流程,分享给大家. 项目开发中,有些需求难免会用到关于快递的一些Api接口:本篇主要介绍的 ...

  3. python中类的创建_如何在python中为类动态创建类方法

    1.基本思想:使用额外的类来保存方法 我找到了一种有意义的工作方式: 首先,我们定义这样的BaseClass: class MethodPatcher: @classmethod def patch( ...

  4. 二叉树的创建_【数据结构用python描述】python创建二叉树

    接下来一段时间小编会和大家一起学习数据结构用python描述. C/C++可以通过使用链表来创建二叉树,当然python也可以,但是现在的问题是 python没有指针和引用.C/C++创建链表二叉树需 ...

  5. node aws 内存溢出_如何使用Node.js和AWS快速创建无服务器RESTful API

    node aws 内存溢出 by Mark Hopson 马克·霍普森(Mark Hopson) 如何使用Node.js和AWS快速创建无服务器RESTful API (How to quickly ...

  6. swagger api文档_带有Swagger的Spring Rest API –创建文档

    swagger api文档 使REST API易于使用的真正关键是好的文档. 但是,即使您的文档做得很好,您也需要设置公司流程的权利以正确,及时地发布它. 确保利益相关者按时收到是一回事,但是您也要负 ...

  7. rest api是什么_一文搞懂什么是RESTful API

    RESTful接口实战 首发公众号:bigsai 转载请附上本文链接 文章收藏在回车课堂 前言 在学习RESTful 风格接口之前,即使你不知道它是什么,但你肯定会好奇它能解决什么问题?有什么应用场景 ...

  8. api网关选型_如何轻松打造百亿流量API网关?看这一篇就够了(下)

    如何轻松打造百亿流量API网关?看这一篇就够了(上) 上篇整体描述了网关的背景,涉及职能.分类.定位环节,本篇进入本文的重点,将会具体谈下百亿级流量API网关的演进过程. 准备好瓜子花生小板凳开始积累 ...

  9. jstree中文api文档_开发中文 API 的一些策略

    注:本文仅基于个人在其他英文编程语言中实现中文 API 的有限实践和见闻,对易语言等等中文编程语言的生态不甚了解,各种疏漏请指正. 如果要现在的我,选择一个英文 API 进行中文化,或者针对一种功能开 ...

  10. python链表的创建_《大话数据结构》配套源码:链表(Python版)

    该书随书源码的语言为C:我参考书中内容和配套源码,写了一套Python格式的配套源码.这套配套源码并非直接翻译C语言的配套源码,而是结合我的理解略作了修改. SinglyLinkedNode 单链表结 ...

最新文章

  1. 《Nature》挑战进化DNA突变理论!
  2. python是全栈_Python全栈之路-3-字符串
  3. efcore 更新关联表_如何在生产环境下用好EFCore
  4. 自研海外PCDN系统技术架构与演进
  5. 以太坊PoA共识引擎算法介绍(1)
  6. php获取pc访问还是手机号_PHP函数判断电脑端浏览器访问访问还是手机端浏览器访问...
  7. 调用内部类里,在静态类中调用动态方法的问题
  8. Cmailserver和outlook配置
  9. 机器学习(一)绪论、算法总结
  10. Java修改文件MD5值-yellowcong
  11. Presto(即席查询)笔记
  12. c语言中用于获取字符串长度的函数是,C语言字符串长度
  13. 马云收购恒生电子几大关键问题
  14. 天啦撸,联合开发网竟然倒闭了!!!(分享一个非常牛的人工智能教程!!!)
  15. 人工智能研究中心快递柜——代码分析十
  16. 浅谈区块链技术应用场景
  17. Bokeh可视化笔记——x轴设为日期
  18. BlockChain初识
  19. 揭秘三个霸道的引流方法 为你扫清没流量的烦恼
  20. Fast Affine Template Matching over Galois Field仿射模板匹配数据测试问题

热门文章

  1. Java 每半年就会更新一次新特性,再不掌握就要落伍了:Java16 的新特性
  2. 工作经验分享|你在工作中应该注意什么?
  3. potato电脑版连接不上_土豆电脑版-potato chat下载 v2.13.200323 电脑版 - 安下载
  4. 采集天眼查的10个经典方法
  5. 单片机入门——流水灯介绍
  6. 对《致加西亚的信》的异议
  7. Oracle数据库管理(一):创建和删除数据库
  8. vue3+ts 全局挂载以及声明写法
  9. 怎么修改html上的文字大小,网页字体大小怎么改_电脑网页字体怎么调整-win7之家...
  10. [MRCTF2020]你传你马呢