HTTP API Call for Cloud Development

Posted by trinitywave on Thu, 19 Sep 2019 13:07:48 +0200

httpApi calls for small program cloud development.

httpApi call for small program cloud development (returning "47001 processing")

Technology stack

Using node JS + express to build web server and axios to request third party http Api

nodejs
express
axios

Project structure

An application skeleton can be created quickly through the application generator tool express-generator.

The main core files are routes/base.js(api settings), util/rq.js(axios encapsulation), views/base.pug (interface documents)

  
| bin (Framework Generation, Service Start Command Folder)
| public (Framework Generation, Static Resource Storage)
|-------images
|-------javascripts
|-------stylesheets
 | routes (Framework Generation, Routing Configuration/api)
| - Base.js//base related interface and documentation page
 | - util (self-adding folders, placing public js)
| ------- result.js// final return result wrapper JS
 | - rq.js//axios package
 | views
|-------error.pug
 | base.pug
|-------index.pug
|-------layout.pug
 | app.js (Framework Generation, Project Core)

  • axios package (util/rq.js)
// Module reference
let axios = require("axios")
let qs = require("qs")

// Variable declaration
const CONFKEY = "dev"
const BASECONF = {
    "dev":{
        baseUrl:'https://api.weixin.qq.com/',
    },
    "prod":{
        baseUrl:'https://api.weixin.qq.com/'
    }
}[CONFKEY]

// Create rq requests and set basic information
const rq = axios.create({
    baseURL: BASECONF.baseUrl,
    timeout: 10000,
    headers: { // Request header settings (Weixin Cloud Development Data APi uses application/json format for reference, otherwise it will result in 47001 error)
        "Content-Type":"application/json; charset=utf-8"
    }
})

// axios request header interceptor
rq.interceptors.request.use(req => {
    // If necessary, intercept the request for participation here for processing.
    return req
},error => {
    return Promise.reject(error)
})

// axios return information interceptor
rq.interceptors.response.use(res => {
    return res.data
},error => {
    return Promise.reject(error)
})

const $rq = { // Encapsulate get,post requests

    get(url,params) { // axios.get(url,config)
        return rq.get(url,{
            params: params
        })
    },
    post(url,params={}) {
        return rq({ // axios(config)
            url: url,
            method: 'post',
            data:params
        })
    }
}

module.exports = {
    $rq
}

  • api settings (routes/base.js)
var express = require('express');
var router = express.Router();
var { $rq } = require("../util/rq")
let result = require("../util/result.js")

/* GET base page. */
router.get('/', function(req, res, next) { // base pugApi description document
    res.render('base', { title: 'baseApi', 
        apiList:[
            {
                url:"base/getAccessToken(Request third party Api,Obtain access_token)",
                method:"GET",
                params:{
                    key:"grant_type",
                    appid:"Small program appid",
                    secret: "Widget key"
                },
                result:{
                    "success": true,
                    "data":`{
                        "access_token":"23_w0OtD1X72LIQo4dwctVsp99kjtIRRk9Gw5bx7UOglotfL7k9LqB1gKbZw86CNht6cnCv9oKBcFEcPg5u4seXN0hJMSEocsbun2dQxCTyZarP06YcToVbdP-MOLc7o7EhMSzqR4URT__BdZc-NMLbAIARQP",
                        "expires_in":7200
                    }`
                }
            },
            {
                url:"base/getdatabase(Get the set information for the specified cloud environment)",
                method:"post",
                params:{
                    env:"Cloud Development Database Environment id",
                    limit:"Access Quantity Limitation,Default 10",
                    offset:"Offset,Default 0"
                },
                result:{
                    "success": true,
                    "data":`{
                        {
                        "errcode": 0,
                        "errmsg": "ok",
                        "collections": [
                            {
                                "name": "geo",
                                "count": 13,
                                "size": 2469,
                                "index_count": 1,
                                "index_size": 36864
                            },
                            {
                                "name": "test_collection",
                                "count": 1,
                                "size": 67,
                                "index_count": 1,
                                "index_size": 16384
                            }
                        ],
                        "pager": {
                            "Offset": 0,
                            "Limit": 10,
                            "Total": 2
                        }
                      }
                    }`
                }
            }
        ]
    });
});

router.get('/getAccessToken', function(req, res, next) { // Request third party Api to get access_token
    let urlParam = { // appID, secret information is best not exposed to the outside world, so write to death directly here.
        grant_type:"client_credential",
        appid: "appid",
        secret: "secret"
    };
    $rq.get("cgi-bin/token",urlParam).then(response=>{
        global.TOKEN_INFO = response // Global node JS global object, occupying memory
        let r =  result.createResult(true, response); // Return results are wrapped in a fixed format
        res.json(r);
    }).catch(err=>{
        let r =  result.createResult(false, err);
        res.json(r);
        console.log(err)
    })
});

router.get('/getdatabase', function(req, res, next) { // Get the set information for the specified cloud environment
    let urlParam = { // Access_token is acquired before other interfaces can be invoked. The input parameters of other interfaces do not need to be passed in access_token because they all need to be spliced behind the interfaces.
        // access_token: req.query.access_token?req.query.access_token:"",
        env: req.query.env?req.query.env:"test-3b6a08",
        limit: req.query.limit?req.query.limit:10,
        offset: req.query.offset?req.query.offset:0
    };
    $rq.post("tcb/databasecollectionget?access_token="+global.TOKEN_INFO.access_token,urlParam).then(response=>{
        let r =  result.createResult(true, response);
        res.json(r);
    }).catch(err=>{
        let r =  result.createResult(false, err);
        res.json(r);
        // console.log(err)
    })
});

module.exports = router;

  • Configure app.js to make routing and interfaces work (only)
var createError = require('http-errors'); // Handling errors
var express = require('express');
var path = require('path'); // Route
var cookieParser = require('cookie-parser'); // cookie
var logger = require('morgan'); // Journal
var sassMiddleware = require('node-sass-middleware'); // sass Middleware

var indexRouter = require('./routes/index'); // index routing
var baseRouter = require('./routes/base') // base routing

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views')); // Setting View Root Directory
app.set('view engine', 'pug'); // Using pug templates

// Declare the use of Middleware
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(sassMiddleware({
  src: path.join(__dirname, 'public'),
  dest: path.join(__dirname, 'public'),
  indentedSyntax: true, // true = .sass and false = .scss
  sourceMap: true
}));
app.use(express.static(path.join(__dirname, 'public')));

app.all('/*',function (req, res, next) { // Solving the problem of leapfrogging
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With');
  res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  if (req.method == 'OPTIONS') {
    res.sendStatus(200);
  }
  else {
    next();
  }
});

// Declarative routing
app.use('/', indexRouter);
app.use('/base', baseRouter);

// catch 404 and forward to error handler custom404middleware
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler Custom Error Throwing Middleware
app.use(function(err, req, res, next) { 
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

So far, the small program cloud development - - httpApi call has been completed.

Simply use vue+elementui to do a cloud development applet background management page call under the above interface.

Let's see the effect as follows:

Cloud development small program background management environment adjustment:

[External Link Picture Transfer Failure (img-zKIBfjWX-1568888441887) (http://m.qpic.cn/psb?/V12a5mB10IdFhp/yBfumzffZjvYU6cwtEzBSXMqaNM4aX07dzAmP6bpmo!/b/dLgAAAAA&bo=6AFAQAAF7viewer!&rf=5)]

Locally start the above service and call result:

Local Start Interface Service

[Img-yUwMF8E3-1568888441888 (http://m.qpic.cn/psb?/V12a5mB10IdFhp/LOqYwnfdrtthoj6QpK0*GT5dlcCBmR2mOSfB5Q0Hz Ls!/b/dDYBAAAAAA&bo=pwK3AwAAFM!&rf=viewer_4&t=5)]

Local interface call result

[Img-rNSWzFAl-1568888441888 (http://m.qpic.cn/psb?/V12a5mB10IdFhp/OEOh8aWJ1.sR55vln74d4WVKsxIMYBbAETQeu2yOeA!/b/dFMBAAAAAA&bo=NQfxAwAAAD!&rf=er_4&t=5)]

The interface is uploaded to the server call result:

[Img-Od1CNl0X-1568888441889 (http://m.qpic.cn/psb?/V12a5mB10IdFhp/1E5iYVdHdytfBHRBGhzADB21WpXOIXg89bc64!/b/dFMBAAAAAA&bo=NQfxAwAAADF*I!&rf=viewer_4&t=5)]

So far, the small program cloud development - - httpApi calls completed.

Problems encountered in the process

  • The third party returns the error code "47001" when the database collection information is retrieved by post.
    Check on the internet, there are many people who have encountered this problem. But how to solve the problem is mostly not clear, or unresolved, or solve the problem that the post is not updated.

  • When I encounter this problem, I first searched the relevant questions in the official community, found the official response, and tried to call on postman. If it is not harmful, please check your code.

  • According to my own words, I checked a wave on postMan and found that no matter how I changed the entry format, it was still a "47001" error. At this time, my participation is as follows:

     {
         access_token:"Acquired access_token",
         env: "Cloud development environment Id",
         limit: 10,
         offset: 0
     }

  • Check the corresponding http Api documents many times, and constantly think about where the problem lies. There's nothing wrong with your code. Why? Would it be a question of participation? access_token has been spelled on the request url once. Does it not need to be added? What is the format of the entry? The default form of post is "application/x-www-form-urlencoded" or "application/json;" and as you can see in another blog post, the format of interface input provided by Wechat is "application/json".

  • Locked in the entry format, but then postMan I tried all the entry formats again, then try to get rid of access_token in the entry format?

  • ok, it's a great success. Eventually I saw the normal return data.

  • Summarize two points:

1. The input format is "application/json; charset=utf-8";

2. To splice the access_token interface, please delete the access_token code as above

If you want to know more about CloudBase related technology stories / technology warfare experience, please pay close attention to the public numbers of Tencent Cloud Development.

Topics: axios JSON sass Database