Write a Restful API

  • Representational State Transfer, which translates as’ layer State changes, ‘is an architectural principle for Internet software. Because WEB API designs conform to the REST style, they are called Restful apis
  • Restful is currently the most popular API specification and is suitable for web interface specification design. Make the interface readable and clear.

1. The URL design

1.1 Verb + object

The idea is that the data manipulation instructions sent by the client are constructed with verbs and objects, such as GET/articles, where GET is the verb and /acticles is the object

  • GET: Reads resources
  • POST: Creates a resource
  • PUT: Updates resources
  • PATCH: Updates some data of resources
  • DELETE: deletes resources

The right example

  • GET/zoos: List all zoos
  • POST/ upshot: A new zoo
  • GET/zoos/ID: GET information about a specified zoo
  • PUT/zoos/ID: Update information for a specified zoo (to get all information about that zoo)
  • PATCH/zoos/ID: Update information for a specified zoo (get partial information for that zoo)
  • DELETE/zoos/ID: Deletes a zoo
  • GET/zoos/ID/animals: Lists all the animals in a given zoo
  • DELETE/zoos/ID/animals/ID: DELETE a specified designated animals at the zoo

1.2 Verb overwriting

Some clients can only use GET and POST. The server must accept POST to simulate the other three methods (PUT, PATCH, and DELETE). In this case, the HTTP request sent by the client is added with the x-HTTP-method-Override attribute, which tells the server which verb to Override the POST Method

1.3 The object must be a noun

It’s the URL of the API, it’s the object of the HTTP verb, so it should be a noun. For example, the /books URL is correct, while the following urls are not nouns and are written incorrectly.

Error model

GET /getAllUsers? name=jl POST /createUser POST /deleteUserCopy the code

1.4 Plural Nouns

URL is a noun, so is it plural or singular?

There are no rules, but most of the data we manipulate is a set, like GET /books, so we use complex numbers.

For example, GET /books/2 is better than GET /book/2

1.5 Avoid multi-level urls

Sometimes the resources we need to manipulate may have multiple levels, so it’s easy to write multilevel urls, such as getting a book that sits in a certain category

GET/authorship / 2 / categories / 2 for the author id of 2 articles classified as 2

This KIND of URL is not extensible and semantically clear.

Better yet, all levels except the first are expressed as query strings.

GET /authors/2? categories=2

2. [‘ t? : n]

Status code If there are many records, the server cannot return them all to the user. The API should provide parameters that filter the return results

Here are some common parameters

  • ? Limit =10: Specifies the number of records to return
  • ? Offset =10: Specifies the start of the return record
  • ? Page =2&per_page=100: Specifies the number of pages and the number of records per page
  • ? Sortby = name&ORDER = ASC: specifies which attribute of the slice to order the returned results by, and in what order
  • ? Animal_type_id =1: Specifies a filter condition

2.1 The status code must be accurate

The server must respond to requests from clients, including HTTP status codes and data.

The HTTP status code is a three-digit number divided into five categories.

  • 1xx: Related information
  • 2xx: The operation succeeded
  • 3xx: redirection
  • 4xx: Client error
  • 5xx: Server error

2.2 2XX status code

200 Status code indicates that the operation succeeded, but different methods can return a more accurate status code

  • GET:200
  • POST:201 Created
  • PUT:200 OK
  • PATCH:200 OK
  • DELETE:204 No Content

2.3 4XX Status code

The 4XX status code indicates an error on the client

  • 400 Bad Request: The server does not understand the Request from the client and does not perform any processing
  • 401 Unauthorized: The user does not provide authentication credentials or fails to pass authentication
  • 403 Forbidden: Users are authenticated but do not have the required permissions to access resources
  • 404 Not Found: The requested resource is Not Found or unavailable
  • 405 Method Not Allowed: The user has been authenticated, but the HTTP Method used is Not within his permissions
  • 410 Gone: The requested resource has been moved from this address and is no longer available
  • 415 Unprocessable Media Type: The return format required by the client is not supported. For example, the API can only return JSON, but the client requires XML
  • 422 Unprocessable Entity: The request fails because the attachment uploaded by the client cannot be processed
  • 429 Too Many Requests: The number of Requests from the client exceeded the threshold

2.4 5XX status code

5XX status code Indicates a server error. In general, the API does not disclose the details of the road server to the user, so only two status codes are required

  • 500 Internal Server Error: The client request is valid, but an accident occurs when the Server processes it
  • 503 Service Unavailable: The server cannot process the request, which is generally used for website maintenance status

3. The server responds

3.1 Do not return plain text

The data format returned by the API should not be plain text, but should be a JSON object, so that standard structured data can be returned. Therefore, the content-Type attribute of the HTTP header that the server responds to should be set to Application/JSON

When making a request, the client should also explicitly tell the server that the JSON format is acceptable, that is, the ACCEPT attribute of the HTTP header of the request should also be set to Application/JSON

3.2 Do not return the 200 status code when an error occurs

Koa operational tasks

Koa cross-domain

1. Download and import koA2-CORS

2.app.use(cors())

const koa = require('koa');
const cors = require('koa2-cors');
const app = new koa();
app.use(cors());
Copy the code

Koa uploads files

1. Download and reference Koa-Multer

2. Create a configuration to specify the file saving path and change the file name

Use multer.diskStorate({first object destination writes file save path},{second object changes file name})

Specific usage reference article github.com/expressjs/m…

3. Load the configuration

Const upload = multer({storage: config name})

Upload. Single (‘ file name from the front end ‘)

Single for single file cases refer specifically to the link above

// File upload
const multer = require('koa-multer');
// Configure disk storage
const storage = multer.diskStorage({
  // File save path
  destination: function (req, file, cb) {
    cb(null.'public/images/')},// Change the file name
  filename: function (req, file, cb) {
    var fileFormat = (file.originalname).split(".");  // The last item of the array is the suffix name
    cb(null.Date.now() + "." + fileFormat[fileFormat.length - 1]); }})// Load the configuration
const upload = multer({ storage: storage });
router.post('/upload', upload.single('avatar'), (ctx, next) = > {
  // ctx.req.file is the information of the Avatar file
  // ctx.req.body Text field data if present
  // ctx.body = 'uploads successfully ';
  console.log(ctx.req.file.filename);
  ctx.body = {
    ok: 1}})Copy the code

Form validation

1. Download and import Koa-Bouncer

const bouncer = require('koa-bouncer');
app.use(bouncer.middleware());
Copy the code

2. See the code comment to see how to use it

router.post('/'.async (ctx, next) => {
  // ctx.request.body
  // uname pw1 pw2
  try {
    ctx.validateBody('uname')
      .required('Username is required') // Only uname field is required
      .isString() // Make sure the input field is a string or can be converted to a string
      .trim() // Clear Spaces
      .isLength(6.12.'Username must be 6-12 digits')

    ctx.validateBody('email')
      .optional()
      .isString()
      .trim()
      .isEmail('Illegal email format')

    ctx.validateBody('pwd1')
      .required('Password is mandatory')
      .isString()
      .isLength(6.16.'Password must be 6 to 16 characters')

    ctx.validateBody('pwd2')
      .required('Password must be mandatory')
      .isString()
      .eq(ctx.vals.pwd1, 'Two different passwords')

    // Check whether the database has the same value
    // ctx.validateBody('uname')
    // .check(await db.findUserByUname(ctx.vals.uname),'Username taken')
    // ctx.validateBody('uname').check(' Tom ', 'username already exists ')

    // If the code executes at this point, the verification passes
    // The validator populates the · ctx.VALS · object with the purified values
    console.log(ctx.vals);
    ctx.body = {
      ok: 1}}catch (error) {
    // Check exception special judgment
    if (error instanceof bouncer.ValidationError) {
      ctx.status = 400
      ctx.body = 'Verification failed :' + error.message;
      return;
    }
    throw error
  }
})
Copy the code

Graphic verification code

1. Download and import Trek-Captcha

2. Write the capTCHA interface to obtain the random verification code

const captcha = require('trek-captcha');
router.get('/captcha'.async (ctx, next) => {
  const { token, buffer } = await captcha({ size: 4 });
  // // Function of the token Compares the verification code with the token after it is entered
  ctx.body = buffer;
})
Copy the code

3. If the front end wants to change the random captcha, it can add the time Date now () to the request data SRC.

changeCaptcha() { this.$refs.captcha.src = '/users/captcha? r=' + Date.now(); },Copy the code

This.$refs.captcha is the tag of a captcha that returns a different captcha for each request

The article refers to teacher Ma Ge from Luffy School City