preface

Wechat cloud development is wechat small program launched for a long time, recently looked at the cloud development document, ready to start to write a small program to practice hand.

The front-end module uses a project built with UNI-app that was written before, and the cloud development module is rebuilt.

1. Create wechat mini programs

First create a small program in wechat development tools, fill in your AppID, back-end service select small program cloud development.

The directory structure is as follows:

Cloudfunctions are cloudfunction directories, and miniProgram is a small program front-end module.

Because I’m going to use uni-app for the front end module, I have to change it. Delete the miniProgram directory and copy the code for vue-CLI to create uni-app project.

Run NPM run dev:mp-weixin. The final directory is as follows:

2, re-specify the small program front-end module directory

Modify uni-app package output path: Dev builds the platform code in the /dist/dev/ root directory. Build builds the platform code in the /dist/build/ root directory. It is not friendly to fix the small program directory.

Change package.json scripts dev:mp-weixin and build:mp-weixin commands:


"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin UNI_OUTPUT_DIR=dist/build/mp-weixin vue-cli-service uni-build"."dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin UNI_OUTPUT_DIR=dist/build/mp-weixin vue-cli-service uni-build --watch".Copy the code

Add UNI_OUTPUT_DIR=dist/build/mp-weixin and specify the output directory as dist/build/mp-weixin

Dist /build/mp-weixin: dist/build/mp-weixin

 "miniprogramRoot": "dist/build/mp-weixin/".Copy the code

After the modification is complete, open the wechat development tool and the small program can be run.

3. Cloud development

Initialize the

In the cloud development Settings panel, create a new environment with env as the environment ID

The small program end

Add an initialization method to SRC /main.js

wx.cloud.init({
  env: '5175aa'./ / environment
  traceUser: true.// Whether to record user access to user management, visible in the console
})
Copy the code

The function of cloud end

// Initialize cloud
cloud.init({
  // The API calls are kept consistent with the current environment of the cloud function
  // env: cloud.DYNAMIC_CURRENT_ENV
  env: '5175aa'
})
Copy the code

4. Write your first cloud function

Cloud function

Delete all files in the Cloudfunctions folder and create a new cloudfunction called main:

config.json

{
  "permissions": {
    "openapi": []}}Copy the code

package.json

{
  "name": "echo"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": ""."license": "ISC"."dependencies": {
    "wx-server-sdk": "~ 2.4.0." "}}Copy the code

index.js

// Cloud function entry file
const cloud = require('wx-server-sdk')

cloud.init({
  // The API calls are kept consistent with the current environment of the cloud function
  // env: cloud.DYNAMIC_CURRENT_ENV
  env: '5175aa'
})

// Cloud function entry function
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  return {
    event,
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  }
}

Copy the code

A cloud function is done, and we can now debug locally or upload to the cloud for deployment.

Local Debugging Steps

Go to the cloudfunctions/main directory to install NPM I and right-click to enable local debugging of cloudfunctions

Upload to cloud deployment

Applet side call

wx.cloud.callFunction({
  // Cloud function name
  name: 'mian'.// The parameters passed to the cloud function
  data: {
    a: 1.b: 2,},success: function(res) {
    console.log(res.result.sum) / / 3
  },
  fail: console.error
})
Copy the code

Of course, promise-style calls are also supported:

wx.cloud.callFunction({
  // Cloud function name
  name: 'main'.// The parameters passed to the cloud function
  data: {
    a: 1.b: 2,
  },
})
.then(res= > {
  console.log(res.result) / / 3
})
.catch(console.error)
Copy the code

The request succeeded.

5. Cloud function routing optimization TCB-Router

Cloud functions also have some disadvantages:

  • A wechat applet can only create 50 cloud functions, which cannot meet complex business needs.

  • Each cloud function needs to maintain a copy of package.json

So we need to optimize with TCB-Router, which is a KOA-style cloud function routing library.

The installationtcb-router:

In the cloudfunctions/main directory

npm i tcb-router -S

incloudfunctions/main/index.jsModified to:

const cloud = require('wx-server-sdk')
const TcbRouter = require('tcb-router')
cloud.init({
  // The API calls are kept consistent with the current environment of the cloud function
  // env: cloud.DYNAMIC_CURRENT_ENV
  env: '5175aa'
})

// Cloud function entry function
exports.main = async(event, context) => {
  const app = new TcbRouter({
    event
  })
 // Global middleware
  app.use(async(ctx, next) => {
    console.log('Enter global middleware')
    await next()
    console.log('Exit global middleware')
  })
  app.router('add'.async(ctx, next) => {
    ctx.body = {
      data: 'Added successfully'
    }
  })	
  app.router('movie'.async(ctx, next) => {
    ctx.body = {
      data: 'output'}})return app.serve()
}

Copy the code

Applet side call

   wx.cloud.callFunction({
      name: 'main'.data: {
        $url: 'add'
      },
    }).then((res) = > {
      console.log(res)
    })
    
    wx.cloud.callFunction({
      name: 'main'.data: {
        $url: 'movie'
      },
    }).then((res) = > {
      console.log(res)
    })

Copy the code

Cloud function modularization

We can split the implementation of the route into js files:

Create common/index.js under Cloudfunctions /main

Exports.login = async (CTX, next) => {console.log(ctx.cloud) console.log(ctx.db) ctx.body = {data: 'output'}}Copy the code

In cloudfunctions/main/index, js, use the require import, and cloud, the db object can then mount to CTX object, in the implementation modules you can use the CTX. Cloud, CTX. Db call object

// Cloud function templates
// Deploy: Right click in the Cloud-functions /login folder and choose upload and deploy

const cloud = require('wx-server-sdk')
const TcbRouter = require('tcb-router');

// Public module
const common = require('./common/index')

// Initialize cloud
cloud.init({
  // The API calls are kept consistent with the current environment of the cloud function
  // env: cloud.DYNAMIC_CURRENT_ENV
  env: '5175aa'
})
const db = cloud.database()

exports.main = async (event, context) => {
  const app = new TcbRouter({event});
  // app.use Indicates that the middleware applies to all routes
  app.use(async (ctx, next) => {
    ctx.db = db;
    ctx.cloud = cloud;
    console.log('Enter global middleware')
    await next()
    console.log('Exit global middleware')});// Authorize login
  app.router('/login', common.login)


  return app.serve();
}

Copy the code

Global exception capture middleware

At this point, application development is ready, but as anyone who has used KOA knows, we still need a global exception capture middleware to handle server errors in a unified manner.

Create a new utility class utils/index.js

module.exports = {
  // Manually reported an error
  throwError(code = 400, msg = 'Server error') {
    const err = new Error(msg);
    err.code = code;
    err.msg = msg;
    throwerr; }};Copy the code

In cloudfunctions/main/index. Js

const utils = require('./utils/index')

// app.use Indicates that the middleware applies to all routes
  app.use(async (ctx, next) => {
    ctx.db = db;
    ctx.cloud = cloud;
    ctx.utils=utils  // Mount the tool class
    try {
      await next();  // Throw an error at the next link
    } catch (err) {
      // Manually throwing an exception throwError function is triggered
      if (err.msg) {
        ctx.body = {
          code: err.code,
          data: ' '.msg: err.msg,
        };
      } else {
      // Automatic error
        ctx.body = {
          code: 500.data: ' '.msg: Server internal error:+ err, }; }}});Copy the code

test

Manually throwing an exception

Exports.login = async (CTX, next) => {ctx.uilts.throwError('500',' manual throw exception ') ctx.body = {data: 'output'}}Copy the code

Return to success

Internal error exception

exports.login = async (ctx, next) => { console.log(a); Ctx. body = {data: 'output'}}Copy the code

Return to success

7. Add, delete, check and change the database

Cloud development of the database, front-end and cloud functions can be operated, but in the front-end database operation has relatively big disadvantages:

  • Request list data, direct operation database can only return 20 at a time, cloud function can return 100;
  • There is also a direct call to the database, all the add, delete, change and check operations are run locally in the mobile phone, if the amount of data is large, it will consume user traffic, while the cloud function is calculated on the wechat server.
  • Security issues, may be malicious attacks

Therefore, it is recommended to do database operations in the cloud.

Initialize the

In the Cloud Development panel, create a new collection user (table)

Initialization in the cloud function

const db = cloud.database()
Copy the code

Insert data

db.collection('user').add({
  // Data indicates the JSON data to be added
  data: {
    // _id: 'todo-identifiant-aleatoire', // Optional custom _id, in this scenario, automatic database assignment is ok
    description: "learn cloud database".due: new Date("2018-09-01"),
    tags: [
      "cloud"."database"].// Add a location for the to-do list (113°E, 23°N)
    location: new db.Geo.Point(113.23),
    done: false
  },
  success: function(res) {
    // res is an object with the _ID field marking the ID of the newly created record
    console.log(res)
  }
})
Copy the code

Get the data of a record

db.collection('user').doc('todo-identifiant-aleatoire').get().then(res= > {
  // res.data Contains the data for the record
  console.log(res.data)
})

Copy the code

Get data for multiple records

We can also retrieve multiple records at once. You can specify the query criteria by calling the WHERE method on the collection, and then calling the GET method to return only records that meet the specified query criteria, such as getting all of the user’s outstanding to-do lists:

db.collection('user').where({
  _openid: 'user-open-id'.done: false
})
.get({
  success: function(res) {
    Res.data is an array containing the two records defined above
    console.log(res.data)
  }
})
Copy the code

Update the data

db.collection('user').doc('todo-identifiant-aleatoire').update({
  // data Passes in data that needs to be locally updated
  data: {
    // Sets the done field to true
    done: true
  },
  success: function(res) {
    console.log(res.data)
  }
})
Copy the code

Delete a record


db.collection('user').doc('todo-identifiant-aleatoire').remove({
  success: function(res) {
    console.log(res.data)
  }
})
Copy the code

You can check wechat’s official documentation for more usage

Small program side request cloud function encapsulation

For unified management and easy to call, we can encapsulate the method of small program side request cloud function

Create a new file SCR /config/http.js

const http = function (param) {
  const isHideToast = param.isHideToast || false;  // Whether to hide the error message
  return new Promise((resolve, reject) = > {
    wx.cloud.callFunction({
      // The name of the cloud function to call
      name: param.moduleName || "main".// The parameters passed to the cloud function
      data: {
        $url:param.url, ... param.data } }).then(res= > {
      if (res.result) {
        if (res.result.code === 200) {
          resolve(res.result.data);
        } else {
          if (isHideToast) {
            uni.showToast({
              title: res.result.data.msg || 'Return failed'.duration: 1500.icon:'none'}); } reject(res.result.data); }}else {
        uni.showToast({
          title: 'URL does not exist'.duration: 1500.icon:'none'}); }})})}export default http
Copy the code

Then mount the HTTP object to vUE

Under SRC /main.js, add

import http from './api/http'
Vue.prototype.$http = http
Copy the code

On the applet side call:

this.$http({
    url: "/login".data: {}
}).then(res= > {
    console.log(res)
})
Copy the code