最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Displaying pure JSON format with black background in GraphQL Express React - Stack Overflow

programmeradmin0浏览0评论

I'm having issue of displaying the response of the API. It appears white like this

Which is should be similar like this

My code in the backend server:

main.ts

import { typeDefs, resolvers } from './src/graphql/Resolver'

AppDataSource.initialize()
const app = express()
const httpServer = http.createServer(app)
const server = new ApolloServer({
    typeDefs,
    resolvers,
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
});
(async () => {
    await server.start()
    app.use(
        '/gql',
        cors<cors.CorsRequest>({ origin: `http://${process.env.DOMAIN}:${process.env.CLIENT_PORT}`, credentials: true }),
        express.json(),
        cp(),
        expressMiddleware(server, {
            context: async ({ req, res }) => ({ req, res })
        })
    )
    httpServer.listen(process.env.PORT)
})()

Resolver.ts

import API from './resolver/api/Data'
import Books from './resolver/api/Books'

export const typeDefs = Schema
export const resolvers = {
    API: {
        __resolveType(obj: API) {
            if ((obj as Data).user_id) return 'Data'
            else return 'Error'
        }
    },
    Data: {
        books: Books
    },
    Query: {
        api: API
    }
}

Data.ts

const Data = async (_: null, args: { api_key: string }) => {
    try {
        const userRepo = AppDataSource.getRepository(User)
        const { api_key } = args
        const hashBuffer = Buffer.from(api_key, 'hex')
        const user = await userRepo.findOne({ where: { api_key: hashBuffer } })
        if (!user) return { message: 'Invalid API Key!'}
        return {
            user_id: user.user_id,
            email: user.email,
            username: user.username
        }
    } catch {
        throw new GraphQLError('Internal Server Error', { extensions: { code: '500' } })
    }
}
export default Data

Books.ts (the parent refers to Data)

const Books = async (parent: { user_id: number }) => {
    try {
        const bookRepo = AppDataSource.getRepository(Book)
        const books = await bookRepo.find({ where: { user_id: parent!.user_id } })
        return books.map(book => ({
            cover_i: book.cover_i,
            isbn: book.isbn,
            title: book.title,
            author_name: book.author_name
        }))
    } catch {
        throw new GraphQLError('Internal Server Error', { extensions: { code: '500' } })
    }
}
export default Books

Frontend:

App.tsx

const App: React.FC = () => {
    const { loading, data, error } = useQuery(AuthGQL)
    const dispatch = useDispatch()
    React.useEffect(() => {
        if (!loading) {
            if (data) dispatch(setUser(data.auth))
            else if (error) dispatch(setUser(null))
        }
    }, [data, error])
    return (
        <BrowserRouter>
            <main>
                <Routes>
                    <Route path="API/:hash" element={<API />} />
                </Routes>
            </main>
        </BrowserRouter>
    )
}
export default App

API.tsx

interface Book {
    cover_i: string
    isbn: string
    title: string
    author_name: string
    __typename: string
}
const API: React.FC = () => {
    const { hash } = useParams<{ hash: string }>()
    const { loading, data, error } = useQuery(APIGQL, { variables: { api_key: hash } })
    const apiState = useSelector((state: RootState) => state.API)
    const dispatch = useDispatch()
    React.useEffect(() => {
        if (!loading) {
            if (data) {
                const { __typename, books, ...api } = data.api
                dispatch(setApi({
                    ...api,
                    books: books.map(({ __typename, ...book }: Book) => book)
                }))
            }
            else if (error) { }
        }
    }, [data, error])
    return (
        <pre>{JSON.stringify(apiState, null, 2)}</pre>
    )
}
export default API

I have no idea how to displaying like that. Asking GPT forces me to use CSS style while I'm pretty sure the Open Library API doesn't use that way.

I'm having issue of displaying the response of the API. It appears white like this

Which is should be similar like this

My code in the backend server:

main.ts

import { typeDefs, resolvers } from './src/graphql/Resolver'

AppDataSource.initialize()
const app = express()
const httpServer = http.createServer(app)
const server = new ApolloServer({
    typeDefs,
    resolvers,
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
});
(async () => {
    await server.start()
    app.use(
        '/gql',
        cors<cors.CorsRequest>({ origin: `http://${process.env.DOMAIN}:${process.env.CLIENT_PORT}`, credentials: true }),
        express.json(),
        cp(),
        expressMiddleware(server, {
            context: async ({ req, res }) => ({ req, res })
        })
    )
    httpServer.listen(process.env.PORT)
})()

Resolver.ts

import API from './resolver/api/Data'
import Books from './resolver/api/Books'

export const typeDefs = Schema
export const resolvers = {
    API: {
        __resolveType(obj: API) {
            if ((obj as Data).user_id) return 'Data'
            else return 'Error'
        }
    },
    Data: {
        books: Books
    },
    Query: {
        api: API
    }
}

Data.ts

const Data = async (_: null, args: { api_key: string }) => {
    try {
        const userRepo = AppDataSource.getRepository(User)
        const { api_key } = args
        const hashBuffer = Buffer.from(api_key, 'hex')
        const user = await userRepo.findOne({ where: { api_key: hashBuffer } })
        if (!user) return { message: 'Invalid API Key!'}
        return {
            user_id: user.user_id,
            email: user.email,
            username: user.username
        }
    } catch {
        throw new GraphQLError('Internal Server Error', { extensions: { code: '500' } })
    }
}
export default Data

Books.ts (the parent refers to Data)

const Books = async (parent: { user_id: number }) => {
    try {
        const bookRepo = AppDataSource.getRepository(Book)
        const books = await bookRepo.find({ where: { user_id: parent!.user_id } })
        return books.map(book => ({
            cover_i: book.cover_i,
            isbn: book.isbn,
            title: book.title,
            author_name: book.author_name
        }))
    } catch {
        throw new GraphQLError('Internal Server Error', { extensions: { code: '500' } })
    }
}
export default Books

Frontend:

App.tsx

const App: React.FC = () => {
    const { loading, data, error } = useQuery(AuthGQL)
    const dispatch = useDispatch()
    React.useEffect(() => {
        if (!loading) {
            if (data) dispatch(setUser(data.auth))
            else if (error) dispatch(setUser(null))
        }
    }, [data, error])
    return (
        <BrowserRouter>
            <main>
                <Routes>
                    <Route path="API/:hash" element={<API />} />
                </Routes>
            </main>
        </BrowserRouter>
    )
}
export default App

API.tsx

interface Book {
    cover_i: string
    isbn: string
    title: string
    author_name: string
    __typename: string
}
const API: React.FC = () => {
    const { hash } = useParams<{ hash: string }>()
    const { loading, data, error } = useQuery(APIGQL, { variables: { api_key: hash } })
    const apiState = useSelector((state: RootState) => state.API)
    const dispatch = useDispatch()
    React.useEffect(() => {
        if (!loading) {
            if (data) {
                const { __typename, books, ...api } = data.api
                dispatch(setApi({
                    ...api,
                    books: books.map(({ __typename, ...book }: Book) => book)
                }))
            }
            else if (error) { }
        }
    }, [data, error])
    return (
        <pre>{JSON.stringify(apiState, null, 2)}</pre>
    )
}
export default API

I have no idea how to displaying like that. Asking GPT forces me to use CSS style while I'm pretty sure the Open Library API doesn't use that way.

Share Improve this question asked Feb 3 at 17:22 VireZeeVireZee 585 bronze badges 4
  • Open Library API returns raw json, which is displayed in the default font and background of your browser, usually black font over white background except when using something like a dark theme. If you want to control the display you will have to use CSS and or rendering markup for your json – remix23 Commented Feb 3 at 17:32
  • so how do I make return raw json like that, since in the white theres no check mark button like pretty-print. I want to make the same way like open library – VireZee Commented Feb 3 at 17:34
  • I'm using same browser and pc. but get different result – VireZee Commented Feb 3 at 17:37
  • Your API also returns raw json, but you're using react to display it in a web page, which can be styled. So your API is fine but if you want to display it's result in a styled way you can have a look at my answer. – remix23 Commented Feb 3 at 17:42
Add a comment  | 

2 Answers 2

Reset to default 1

You can't do that with GQL since GQL need a POST request. It can't return json like that. But you can combine REST with your GQL.

main.ts

(async () => {
    await server.start()
    app.use(
        '/gql',
        cors<cors.CorsRequest>({ origin: `http://${process.env.DOMAIN}:${process.env.CLIENT_PORT}`, credentials: true }),
        express.json(),
        cp(),
        expressMiddleware(server, {
            context: async ({ req, res }) => ({ req, res })
        })
    )
    // since I saw your format URL is somewhat '/API/hash'
    app.get('/API/:hash', async (req: Request, res: Response) => {
        try {
            const userRepo = AppDataSource.getRepository(User)
            const { hash } = req.params
            const hashBuffer = Buffer.from(hash, 'hex')
            const user = await userRepo.findOne({ where: { api_key: hashBuffer } })
            if (!user) res.status(404).json({ message: 'Invalid API Key!' })
            // continue the logic
            res.status(200).json(JSON.parse(JSON.stringify('return your dict response', null, 2)))
        } catch {
        }
    }
    httpServer.listen(process.env.PORT)
})()

Open Library API returns raw json, which is displayed in the default font and background of your browser, usually black font over white background except when using something like a dark theme. If you want to control the display you will have to use CSS and or rendering markup for your json.

The simplest way here is to style the element you're stringifying your json into:

return (
    <pre style={{ color: 'white'; background: 'black' }}>
       {JSON.stringify(apiState, null, 2)}
    </pre>
);

If you do not want to control the display instead of querying the API in a React component, just navigate to your API endpoint.

look into useNavigate if your API accepts searchParams, otherwise you probably will need a form element

发布评论

评论列表(0)

  1. 暂无评论