Как отправить GET-ответ REST api клиенту React, используя Koa2 и koa-router?

У меня есть REST api, настроенный с помощью koa и koa-router. Я могу попасть в конечную точку api и console.log(ctx.body) и я вижу то, что хочу и ожидаю увидеть. В этом случае я ожидаю увидеть объект json с URL-адресом, и это то, что я вижу на стороне узла, когда консолью его:

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

Однако, когда я пытаюсь использовать конечную точку в React, ответ, который я получаю от клиента, представляет собой объект Response, который выглядит следующим образом:

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

Мой вопрос в том, как мне получить объект json, который я ожидал в моем node console.log выше на клиенте?

Я новичок в koa и пытаюсь изучить его, следуя примерам других людей, как они настраивают свои остальные api. В настоящее время мой сервер выглядит следующим образом:

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);

И мой файл маршрутов выглядит следующим образом:

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());
}

Наконец, мой контроллер выглядит следующим образом:

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);
    }
}

Спасибо, что посмотрели на это и предоставили любую помощь.


person Zigrivers    schedule 24.04.2016    source источник
comment
Вы пробовали curl -i http://localhost:3000/api/verification из командной строки? Таким образом вы можете подтвердить, что ваш сервер является источником ошибки.   -  person pe8ter    schedule 25.04.2016
comment
Никогда раньше не использовал curl, но установил его и применил команду. Похоже, API работает. Я получил заголовки и объект с ключами и данными, которые я ожидал. Заголовки показали: HTTP / 1.1 200 OK Content-Type: application / json; charset = utf-8 X-Response-Time: 306ms Content-Length: 280 Дата: сегодня Соединение: keep-alive {здесь мой ожидаемый объект}   -  person Zigrivers    schedule 25.04.2016
comment
Похоже, проблема не в Koa, а в клиентском коде, который вызывает API.   -  person pe8ter    schedule 25.04.2016


Ответы (1)


@ pe8ter направил меня на правильный путь. Оказалось, что с моим серверным кодом проблем не было, это был мой клиентский код. Я использовал fetch для использования api, но я не обрабатывал обещание, что fetch вернется правильно. Все, что мне нужно было сделать, это изменить мой код на стороне клиента с этого:

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);
        }
    }
}

Я изменил код на этот, чтобы обработать ответ от выборки:

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);
        }
    }
}

И теперь все работает как положено. Спасибо за помощь!

person Zigrivers    schedule 25.04.2016