Next.js: How to use custom server(fetch data) api inside next.js project?

Created on 1 Jun 2017  Β·  9Comments  Β·  Source: vercel/next.js

Hi~ I saw the offical example show fetch data is using by:

static async getInitialProps () {
    const res = await fetch('https://api.github.com/repos/zeit/next.js')
    const json = await res.json()
    return { stars: json.stargazers_count }
}

That meas this fetch-data api is outside our project, but how to use custom server api inside project? I didn't find related solutions in docs, unless I'm overlooking something?

In my question case, I use nodejs module mysql, fs to get data from local database what app needs, and all the api is working well by independent test.

I have try this:

import React from 'react'
import getArticleApi from '../interfaces/api.article'

export default class extends React.Component {
     static getInitialProps ({ query }) {
         console.log(getArticleApi)
         return {}
     }
}

And thorw error:

These modules were not found:

* net in ./~/mysql/lib/Connection.js
* tls in ./~/mysql/lib/Connection.js
* fs in ./~/mysql/lib/protocol/sequences/Query.js

To install them, you can run: npm install --save net tls fs

I think the reason for this problem is probaly that the my custom nodejs server api code was not run in node(server side) correctly.

And here is my project directory structure:

β”œβ”€β”€ README.md
β”œβ”€β”€ components
β”‚Β Β  β”œβ”€β”€ CommonAside.js
β”‚Β Β  └── DocumentHead.js
β”œβ”€β”€ interfaces
β”‚Β Β  β”œβ”€β”€ api.article.js
β”‚Β Β  β”œβ”€β”€ api.articles.js
β”‚Β Β  β”œβ”€β”€ api.titles.js
β”‚Β Β  β”œβ”€β”€ db.js
β”‚Β Β  β”œβ”€β”€ db.json
β”‚Β Β  └── test.js
β”œβ”€β”€ package.json
β”œβ”€β”€ pages
β”‚Β Β  β”œβ”€β”€ article.js
β”‚Β Β  └── index.js
β”œβ”€β”€ server.js
β”œβ”€β”€ static
β”‚Β Β  └── favicon.ico
└── styles
    β”œβ”€β”€ Global.js
    └── Normalize.js

Looking forward to your answer, thank you!

Most helpful comment

Since you cannot do what you are trying to do on the browser, the way to solve this issue is to create a custom route based on express or koa and point your const res = await fetch('/endpoint').

Based on the examples you need to create something like:

server.get('/endpoint', function (req, res) {
  res.send(msqlContent)
})

All 9 comments

Since you cannot do what you are trying to do on the browser, the way to solve this issue is to create a custom route based on express or koa and point your const res = await fetch('/endpoint').

Based on the examples you need to create something like:

server.get('/endpoint', function (req, res) {
  res.send(msqlContent)
})

Thank you! It works.

Hey @tangbc Do you mind sharing with me how exactly you have made it work?
Am interested in making a similar custom server api with next and can't figure out how exactly.
Am total noob btw.

Thanks in advance!

To expand on @jpsc response. isomorphic-unfetch asked for absolute URL. This is my solution:

import fetch from 'isomorphic-unfetch'

static async getInitialProps({ req }) {
    const baseUrl = req ? `${req.protocol}://${req.get('Host')}` : '';
    const res = await fetch(`${baseUrl}/api/getRosters`)
    const data = await res.json()
    return ({
      data
    })
}

Since you cannot do what you are trying to do on the browser, the way to solve this issue is to create a custom route based on express or koa and point your const res = await fetch('/endpoint').

Based on the examples you need to create something like:

server.get('/endpoint', function (req, res) {
  res.send(msqlContent)
})

@jpsc Make sense, however, the isomorphic-fetch throw this error doing this:

Only absolute URLs are supported

How can I fix it?

@aralroca , take a look at @greggootz 's answer! It shows how to dynamically construct an absolute Url for your local express server.

Hi! @greggootz

To expand on @jpsc response. isomorphic-unfetch asked for absolute URL. This is my solution:

import fetch from 'isomorphic-unfetch'

static async getInitialProps({ req }) {
    const baseUrl = req ? `${req.protocol}://${req.get('Host')}` : '';
    const res = await fetch(`${baseUrl}/api/getRosters`)
    const data = await res.json()
    return ({
      data
    })
}

So How do you test for getInitialProps this time

I can get the host from req.headers.host but req.protocol says undefined, any idea?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

baldurh picture baldurh  Β·  74Comments

Vista1nik picture Vista1nik  Β·  55Comments

acanimal picture acanimal  Β·  74Comments

rauchg picture rauchg  Β·  208Comments

nvartolomei picture nvartolomei  Β·  78Comments