英文:
Outputting a JSON API call response from Golang to a nextjs frontend
问题
我得到的错误是:
错误:在“/”中从“getServerSideProps”返回的“.username”的序列化错误。
原因:无法将“undefined”序列化为JSON。请使用“null”或省略此值。
我的后端Go代码正常工作,我可以在Postman上检查它,但是我无法从后端获取API响应以弹出任何反馈或代码改进都是可以的
:Main.go
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
func main() {
handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
var resp []byte
if req.URL.Path == "/status" {
resp = []byte(`{"status": "ok"}`)
} else if req.URL.Path == "/username" {
resp = []byte(GetData())
json.NewEncoder(rw).Encode(resp)
} else {
rw.WriteHeader(http.StatusNotFound)
return
}
rw.Header().Set("Content-Type", "application/json")
rw.Header().Set("Content-Length", fmt.Sprint(len(resp)))
rw.Write(resp)
})
log.Println("Server is available at http://localhost:8000")
log.Fatal(http.ListenAndServe(":8000", handler))
}
:data.go - 此文件用作API的酷JSON响应
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
)
func GetData( ) string {
response, err := http.Get("http://pokeapi.co/api/v2/pokedex/kanto/")
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(responseData))
return ""
}
index.ts是我用于前端的Next.js文件
export async function getServerSideProps() {
const {status} = await fetch("http://localhost:8000/status").then(x => x.json());
const {username} = await fetch("http://localhost:8000/username").then(x => x.json());
let res = await {username: JSON, status: JSON};
console.log("res: ", res);
return {
props: {
status: status,
username: username,
}
}
}
export default function Home({status, username}: {status: any, username: any}) {
return (
<div className="">
<main className="">
<h1 className="">
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>
<div>Status is: {status}, your username is: {username}</div>
</main>
</div>
)
}
英文:
The Error I am getting is
Error: Error serializing `.username` returned from `getServerSideProps` in "/".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.
My backend go is working fine I can check it on postman however I can not get the API response from my backend to pop up any feedback or code improvments are welcome
:Main.go
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
func main() {
handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
var resp []byte
if req.URL.Path == "/status" {
resp = []byte(`{"status": "ok"}`)
} else if req.URL.Path == "/username" {
resp = []byte(GetData())
json.NewEncoder(rw).Encode(resp)
} else {
rw.WriteHeader(http.StatusNotFound)
return
}
rw.Header().Set("Content-Type", "application/json")
rw.Header().Set("Content-Length", fmt.Sprint(len(resp)))
rw.Write(resp)
})
log.Println("Server is available at http://localhost:8000")
log.Fatal(http.ListenAndServe(":8000", handler))
}
: data.go - This file serves as api cool json response
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
)
func GetData( ) string {
response, err := http.Get("http://pokeapi.co/api/v2/pokedex/kanto/")
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(responseData))
return ""
}
index.ts nextjs file that I am using for frontend
export async function getServerSideProps() {
const {status} = await fetch("http://localhost:8000/status").then(x => x.json());
const {username} = await fetch("http://localhost:8000/username").then(x => x.json());
let res = await {username: JSON, status: JSON};
console.log("res: ", res);
return {
props: {
status: status,
username: username,
}
}
}
export default function Home({status, username}: {status: any, username: any}) {
return (
<div className="">
<main className="">
<h1 className="">
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>
<div>Status is: {status}, your username is: {username}</div>
</main>
</div>
)
}
答案1
得分: 1
GetData()
目前返回一个""
。
你可以更新GetData
函数,使其返回[]byte
类型:
func GetData() ([]byte, error) {
response, err := http.Get("http://pokeapi.co/api/v2/pokedex/kanto/")
if err != nil {
return nil, err
}
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}
return responseData, nil
}
然后,你可以将/username
分支更新如下:
} else if req.URL.Path == "/username" {
data, err := GetData()
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
resp = data
}
你的数据已经是JSON的字节,所以你不需要使用json.NewEncoder().Encode
,你可以直接重新赋值resp
并将这些字节直接写入。
如果你确实需要写入JSON,你不能在写入头部之前向响应写入内容,所以如果你需要在写入响应体时进行更复杂的操作,你可能需要调整一下代码中的顺序。
英文:
GetData()
currently returns a ""
You could update GetData
to return []byte
:
func GetData() ([]byte, error) {
response, err := http.Get("http://pokeapi.co/api/v2/pokedex/kanto/")
if err != nil {
return nil, err
}
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}
return responseData, nil
}
You can then update the /username
branch to be as follows:
} else if req.URL.Path == "/username" {
data, err := GetData()
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
resp = data
}
Your data is already bytes of json, so you do not need json.NewEncoder().Encode
, you can just re-assign the resp
value you have and write those bytes directly.
If you did need to do write json you can't write to the response-writer before writing headers, so you might need to move those around if you end up doing more complicated things with writing response bodies.
答案2
得分: 1
你的GetData()函数只返回了一个空字符串。
你可能应该创建一个结构体来解析JSON,并返回解析后的结构体。或者你可以直接传递字节。
英文:
Your GetData() function just returns ""
You should probably create a struct to unmarshal the json into and then return that marshaled. Or you could just pass on the bytes.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论