精装书 API 的乐趣:快速参考
我是 Goodreads 的长期用户,但在跟踪我的图书方面一直想尝试更好的方法。因此,我最近开始使用 Hardcover,这是一个由小型独立团队运营的竞争对手。现在还处于早期阶段,我知道很难击败像 Goodreads 这样大的东西,但我充满希望!
Hardcover 的一大优点是,与 Goodreads 不同,它有一个免费使用的 API,可让您查询存储在 Hardcover 中的书籍上的任何数据。它还可以用于执行您在精装版 UI 中能够执行的任何操作,例如更新您正在阅读的书籍的状态
阅读、将书籍添加到列表等等。
我如何使用 Hardcover 的 API
现在我正在使用 API 生成我网站的书评部分。我从 Hardcover 中获取了所有评论,并将它们存储在 JSON 文件中。然后我循环浏览此列表中的评论,并将它们全部呈现在页面上。
我不太确定如何处理非常短的评论,因此目前我决定在页面上按原样呈现评论(如果评论少于 360 个字符),并链接到单独的页面(如果评论少于 360 个字符)他们的意义远不止于此。
我还添加了一个搜索栏,它将搜索我的所有评论,并且如果评论中有剧透,我还设置了一些文本模糊处理。
将来我想添加一种按星级和流派进行过滤的方法。
开始使用 Hardcover 的 API
Hardcover 的 API 还处于早期访问模式,并且还没有任何适当的文档,因此在这篇文章中我将回顾一些迄今为止我发现有用的查询。 Hardcover 的 Discord 服务器也是获取问题答案的好地方。
您首先需要转到设置页面,并获取精装版 API 密钥。然后您可以在 Hardcover 的 GraphQL 控制台中测试您的查询。
获取您读过的所有书籍
从基本的 GraphQL 查询开始,我们可以使用 status_id 进行过滤,以获取您在精装本中标记为“已读”的所有书籍的书名列表:
{ me { user_books(where: {status_id: {_eq: 3}}) { rating book { title } } } }
我们已将其封装在我中,您可以使用它来查询特定于您的用户的任何内容。
status_id 值的工作方式是:
- 1:一本“想读”的书
- 2:一本“正在阅读”的书
- 3:一本“读过”的书
- 5:“一本没有完成”的书
获取一本书的作者
如果您搜索cached_contributors,您将获得一个包含书籍“贡献者”列表的数组。这将包含一组预定的数据,例如贡献者的姓名、ID 和图像。
{ me { user_books(where: {status_id: {_eq: 3}}) { rating book { title } } } }
他们是“贡献者”而不是“作者”的原因是它还可以包含翻译该书的人的名字。如果有多个作者,他们也会全部出现在列表中。如果您查询的是一本由一位作者撰写的普通小说,则使用列表中的第一项通常就可以了。
缓存版本的查询速度更快,但如果您想要特定的内容,您也可以查询非缓存版本:
book { cached_contributors }
获取书籍的精装书 URL
如果您想获取该书的精装版链接,可以查询其slug:
book { title contributions { author { name } } }
slug 是网站域名后面的字符串,例如在 emgoto.com/hardcover-book-api 上,“hardcover-book-api”位就是 slug。
因此,一旦您获得了 slug,您只需在其开头添加 https://hardcover.app/books/ 即可创建您的精装版 URL。
获取书籍上的流派标签
精装本中的流派标签系统是用户生成的。您可以查询cached_tags,它将按从最多标记到最少标记的顺序返回标记。
book { slug }
获得完整的标签列表后,您可以使用cached_tags['Genre'] 来获取特定于流派的标签。
如果很多人将某本书标记为小说,那么这将是列表中显示的第一个类型。有趣的是,人们喜欢给他们的书贴上奇幻的标签,因此这种类型经常出现在小说标签之前。人们非常喜欢给自己的书贴上奇幻标签,以至于像《沙丘》这样的科幻书籍甚至最终也贴上了科幻和奇幻的标签。
如果您要使用此数据,我建议先对其进行一些清理。例如,如果这本书同时具有奇幻和科幻作为类型标签,则仅使用列表中第一个标签并丢弃另一个标签,因为这更有可能是准确的。
将一本书添加到您的“待读”列表
到目前为止,我只涉及了获取数据,但你也可以使用 Hardcover 的 API 来操作数据 - 当然你不能接触任何其他人的东西,但你可以在自己的 Hardcover 帐户上做的任何事情都是公平的游戏.
如果您有书籍的 ID,您可以通过将其 status_id 设置为 1 将其添加到“待读”列表中:
book { cached_tags }
获取您的书评
这是我用来获取我在精装本中写的所有评论的方法:
{ me { user_books(where: {status_id: {_eq: 3}}) { rating book { title } } } }
我几乎所有的书籍和评论都是从 Goodreads 导入的,我认为有时数据在导入过程中会有点混乱。我发现按 date_added 和 reviewed_at 排序更准确。
我使用 review_raw 值来获取评论文本,其中不包含任何格式(如换行符)。不幸的是,这意味着如果您的评论中有多个段落,API 会将其全部吐出为一个长段落,如下所示:
book { cached_contributors }
使用 JavaScript,我通过执行如下所示的正则表达式来解决这个问题:
book { title contributions { author { name } } }
如果有任何句点后面没有空格,您可以猜测这应该是一个新段落并添加双换行符 nn。这会创建一个新段落。
另一个缺点是剧透标签也丢失了,所以你必须手动添加它们。
还有一个 review_html 值,我认为它可能更有用,但不幸的是它对我来说似乎总是为空。同样,如果您有一篇包含剧透的评论,则会有一个 review_has_spoilers 值,但对于我从 Goodreads 导入的所有书籍,该值都是 false,因此您可能无法依赖它。
按书名和/或作者搜索书籍
精装书的图书搜索非常准确,但他们的 API 中没有 1-1 版本。您可以通过多种方式尝试模仿他们的搜索行为,但快速入门的方法是使用 _eq:
在标题上进行搜索
book { slug }
我按照 users_read_count 排序了图书列表,因为读者数量最多的名为《Dune》的书很可能就是您要查找的《Dune》。
如果您想按标题和作者进行过滤,过滤器查询将如下所示:
book { cached_tags }
如果您不想进行精确的字符串匹配,可以使用 _ilike 查询来代替,它不匹配大小写,因此使用小写字母仍然有效:
mutation addBook { insert_user_book(object: {book_id: 123, status_id: 1}) { id } }
您还可以使用 % 字符作为 _ilike 的通配符,这样就可以
{ me { user_books( where: { _and: [ {has_review: {_eq: true}}, {status_id: {_eq: 3 }} ]} order_by: [ { date_added: desc }, { reviewed_at: desc } ] ) { reviewed_at date_added review_raw rating book { title } } } }
它将匹配任何包含单词“frank”的作者。
顺便说一句,由于 Hardcover 使用 Hasura,谷歌搜索“如何在 Hasura 中执行 X”通常会显示如何执行这些更复杂的查询。
将书籍添加到您的精装书列表中
除了标准的“想读”和“已读”列表外,精装版还具有单独的自定义列表功能。要获取所有列表以及其中的书籍,您可以执行以下操作:
this is the end of one paragraph.And this is the start of the next
将一本书添加到列表中
如果您想将一本书添加到列表中,首先您需要获取列表 ID 和图书 ID。那么就很简单了:
{ me { user_books(where: {status_id: {_eq: 3}}) { rating book { title } } } }
使用 JavaScript 进行 API 调用
一旦您想要退出 GraphQL 控制台,您可以使用 fetch() 进行 API 调用。作为一个非常简单的例子,这是我获取所有评论(我已经将其缩写了一点):
book { cached_contributors }
我必须使构建 fetch 调用变得更容易的编程专业技巧是,如果您:
- 前往精装本
- 在“网络”选项卡中搜索 graphql
- 找到一个看起来有用并且正在返回信息的
- 右键点击网络调用>;复制>复制为提取
它将为您复制一个与我上面粘贴的类似的 fetch 调用,然后您可以在自己的代码中使用它。
关于速率限制的说明
一旦您移出 GraphQL 控制台并开始在脚本中执行操作,如果您尝试同时执行太多操作,则可能会遇到错误或速率限制问题。
例如,当向列表添加一本新书时,我发现尝试同时添加两本书会在 API 中出错,可能是因为它试图将两本书添加到列表中的同一位置。
类似地,如果您尝试发出 100 个不同的调用来根据书名搜索一本书,其中一些调用将会超时。如果您将它们展开并每秒执行一次,如下所示,那么您应该不会遇到任何问题:
book { title contributions { author { name } } }
此外,如果您从 Hardcover 中获取一本书的图像 URL,然后尝试在您的页面上同时加载 100 本书的图像,API 会限制您的速率,并且某些图像将无法加载。我建议在图像标签中添加“loading=lazy”,如下所示:
book { slug }
这样,只有当用户向下滚动查看图像时才会加载图像。
就是这样!我很想知道精装本的下一步发展——我希望它能做得很好,我们终于有了一个 Goodreads 杀手。如果你想在精装本上关注我,我很幸运地找到了 @emma 账号。
以上是精装书 API 的乐趣:快速参考的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。
