简体   繁体   中英

How do I send GET response of REST api to React client using Koa2 and koa-router?

I have a REST api set up with koa and koa-router. I can hit an api end-point and console.log(ctx.body) and I see what I want and expect to see. In this case, I expect to see a json object with a URL and that is what I see on the node side when I console it out:

etrade_api: { oauth_token: 'hidden',
oauth_token_secret: 'hidden',
authorizeUrl: 'https://us.etrade.com/e/t/etws/authorize?key=hidden&token=hidden' }

However, when I try to consume the end-point in React the response I'm getting on the client is a Response object that looks like the following:

Response {url: "http://localhost:3000/api/verification", status: 200, statusText: "OK", headers: Headers, ok: true…}
_abort:false
_raw:Array[0]
body:PassThrough
bodyUsed:false
headers:Headers
ok:true
size:0
status:200
statusText:"OK"
timeout:0
url:"http://localhost:3000/api/verification"
__proto__:Body

My question is how do I get the json object I expected in my node console.log above on the client?

I'm very new to koa and have been trying to learn it by following other people's examples of how they set up their rest apis. Currently my server looks like the following:

import Koa from 'koa';
import convert from 'koa-convert';
import historyApiFallback from 'koa-connect-history-api-fallback';
import serve from 'koa-static';
import body from 'koa-better-body';
import error from 'koa-error';
import compress from 'koa-compress';
import session from 'koa-session';
import responseTime from 'koa-response-time';
import logger from 'koa-logger';
import config from '../settings/config';
import routes from './api/router/routes';


const paths = config.utils_paths;
const app = new Koa();

app.keys = ['somethin up in here'];

app.use(responseTime());
app.use(error());
app.use(logger());
app.use(convert(session(app)));

// Setup api routes
app.use(body());
routes(app);

// This rewrites all routes requests to the root /index.html file
// (ignoring file requests). If you want to implement isomorphic
// rendering, you'll want to remove this middleware.
app.use(convert(historyApiFallback({
    verbose: false
})));

app.use(convert(serve(paths.client('static'))));
app.use(compress());
app.listen(3000);

And my routes file looks like the following:

import Router from 'koa-router';
import account_routes from '../accounts'; //import controllers

export default function (app) {
    const router = new Router({
        prefix: '/api'
    });

    account_routes(router);

    app.use(router.routes());
    app.use(router.allowedMethods());
}

Finally my controller looks like the following:

import etApi from '../etrade_api';

export default function(router){
    router.get('/verification', getEtradeVerificationLink);
    // other routes here
}

async function getEtradeVerificationLink( ctx, next ) {
    const myKey = 'hidden';
    const mySecret = 'hidden';

    try {
        ctx.body = await etApi.requestToken(myKey, mySecret);
        console.log('etrade_api:', ctx.body); // this prints out what I expect to see
    }
    catch ( error ) {
        console.error('Failed to get verification link.', error);
    }
}

Thanks for taking a look at this and providing any help you can.

@pe8ter got me onto the right path. Turns out there wasn't a problem with my server-side code, it was my client-side code. I was using fetch to consume the api, but I wasn't handling the promise that fetch returns correctly. All I needed to do was change my client side code from this:

export function fetchVerificationLink() {
    return async( dispatch ) => {
        dispatch(requestVerificationLink());

        let response, link;
        try {
            response = await read(urls.etradeVerification); // I have a wrapper around node-fetch, but failed to handle the promise that fetch returns

            dispatch(receiveVerificationLink(response));
        }
        catch ( error ) {
            console.error('Unable to get verification link from eTrade.', error);
        }
    }
}

I changed the code to this to handle the response from fetch:

export function fetchVerificationLink() {
    return async( dispatch ) => {
        dispatch(requestVerificationLink());

        let response, link;
        try {
            response = await read(urls.etradeVerification);
            try {
                link = await response.json();  // Here was the solution to my problem.
                dispatch(receiveVerificationLink(link));
            }
            catch ( error ) {
                console.error('Unable to parse authorization link response.', error);
            }                
        }
        catch ( error ) {
            console.error('Unable to get verification link from eTrade.', error);
        }
    }
}

And now everything is working as expected. Thank you for the assist!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM