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