前端er了解GraphQL,看这篇就够了(下)

简介: GraphQL在近几年被提到的次数越来越多,最近参加过的几次技术大会前端分会场均提到过。对于这种光看名字并不容易想到它是什么的东西,还是存在些神秘感的。于是,打算去了解一下GraphQL到底是什么。

那么如果用GraphQL的方式呢?


query shareDetailPage($shareId: Int!, $creatorId:ID!, $start: Int!, $limit: Int = 10) {
    # 分享详情
    shareDetail: share (shareId: $shareId) {
        shareId: id
        title
        desc
        where
        logoUrl
        attchments
    }
    # 评论信息
    commentInfo(shareId: $shareId, start: $start, limit: $limit) {
        totalCount
        comments {
            id
            userId
            content
            commentTime
        }
    }
    # TA的分享
    hisShares (creatorId: $creatorId) {
        shares {
            title
            desc
            where
            startTime
        }
    }
}


一个查询即可搞定。


mutation操作


变更操作,这里只介绍一种场景。到了分享详情页,我们可能会需要编辑这个分享,在传统的方式中,需要调一个更新操作的接口:


POST /api/share/update/:shareId
FormData:
title=xxx&desc=xxx&where=xxx


调完此接口后为了确认确实已经更新成功了,我们可能还会调一次获取分享详情接口:


GET /api/share/:shareId


接下来我们换成GraphQL的方式:


mutation editShareInfo($shareObj: ShareInput!) {
    editShareInfo(shareInfo: $shareObj) {
    shareId: id
    title
    desc
    where
    logoUrl
    attchments
  }
}


这样,便可以直接将分享内容修改并返回修改后的分享详情


其他的功能


为了我们写查询语句部分代码能有更好的可复用性,GraphQL还提供了Fragments(片段), Inline Fragments(内联片段)和Directives(指令)功能。前两者可以类比为JavaScript中的function(函数)和anonymous function(匿名函数),Directives(指令)可以根据我们传的参数来决定某些字段是否需要返回。这里就不做过多介绍了。


以上的功能如何实现?


schema


通过上面的例子,肯定会产生些疑问,我们要如何知道可以查询哪些字段?使用哪些参数?这就需要引入schema了。


通俗点说,schema就是协议,规范,或者可以当他是接口文档。


GraphQL规定,每一个schema有一个根(root)query和根(root)mutation。


我们先来看Root Query怎么写,依然是上面的查询的例子


# 定义一个根查询
type Query {
    # 可以查询的字段和参数
    shares(start: Int = 0, limit: Int = 10, creatorId: ID): [Share!]!
    share(shareId: ID!): Share!
    commentInfo(shareId: ID!, start: Int = 0, limit: Int = 10): CommentInfo!
}


数据类型


如果你熟悉TypeScript或Flow的话可能会发现上面的写法似曾相识,是的,里面的含义就是你想的那样。每一个可以查询的字段的参数后面会跟标明这个参数的类型,!用来表示这个参数不可以是空的。[]表示查询这个字段返回的是数组,[]里面是数组的类型。


上面我们还看到了一些在TypeScript中不存在的类型,比如ID,ID我们暂且把他当成字符串String类型就可以了。类似我们熟悉的JavaScrpit或TypeScript,GraphQL也有几个基础类型,在GraphQL中他们统称叫标量类型(Scalar Type),主要包括:Int(整型), Float(浮点型), String(字符串), Boolean(布尔型)和ID(唯一标识符类型)。同时,GraphQL也允许你去自定义标量类型,例如:Date类型,只需实现相关的序列化,反序列化和验证的功能即可。


对象类型


上面的根查询定义中,我们还看到了一些与业务相关的类型,比如Share, Comment,这些统称为对象类型。对象类型也是GraphQL中的schema的基本组件,他可以告诉我们在服务上可以获得到哪些对象,以及这个对象有哪些字段。接下来我们要做的就是定义这些对象类型,直到全部为基础类型。


# 定义Share的对象类型
type Share {
  id: ID!
  title: String!
  desc: String!
  startTime: Int!
  where: String
  attchments: String
  logoUrl: String
  creatorId: ID!
  lastUpdateTime: Int
  is_delete: Int
  score: Int
  createTime: Int!
}
# 定义评论信息对象类型
type CommentInfo {
  totalCount: Int!
  comments: [Comment!]!
}
# 定义评论对象类型
type Comment {
  id: ID!
  content: String!
  commentTime: Int!
  userId: ID!
  shareId: ID!
}


这样,我们就完成了schema的定义。

其他类型和功能


GraphQL其实还有Enumeration types(枚举类型),Union types(联合类型)。同时,为了代码能更好的复用,GraphQL还提供了 Interface(接口)功能。这里就不做过多介绍了。


实现执行


GraphQL约定,我们需要为Root Query(根查询)和Root Mutation(根变更)里面的每一个字段提供一个resolver的函数。并包装成一个对象暴露出去,就像这样:


const resolvers = {
    // 这里面写查询操作字段的resolver函数
    Query: {},
    // 这里面写变更操作字段的resolver函数
    Mutation: {},
}
export default resolvers


让我们继续写完整:


// 一些加载数据的async function
import { loadSharesFromDB, loadShareById, loadCommentsByShareId } from './datasource'
const resolvers = {
    // 这里面写查询操作字段的resolver函数
    Query: {
        shares: (parent, { start, limit, creatorId }, context, info) => {
            return loadSharesFromDB(start, limit, creatorId)
                    .then(...)
        },
        share: (parent, { shareId }, context, info) => {
            return loadShareById(shareId)
                    .then(...)
        },
        commentInfo: (parent, { shareId, start, limit }, context, info) => {
            return loadCommentsByShareId(shareId, start, limit)
                    .then(...)
        },
    },
    // 这里面写变更操作字段的resolver函数
    Mutation: {
         // ...
    },
}


同样的,对于mutation(变更)操作,我们也是先把schema完成:


# 定义Mutation根入口
type Mutation {
  editShareInfo(shareInfo: ShareInput!): Share! 
}
input ShareInput {
  id: ID!
  title: String!
  desc: String!
  where: String
}


然后,补全resolver函数:


import { updateShareInfo, loadShareById } from './datasource'
const resolvers = {
    Query: {
        // ...
    },
    Mutation: {
        editShareInfo: (parent, { shareInfo }, context, info) => {
            // 更新分享详情,then获取更新后的分享详情
            return updateShareInfo(shareInfo.id, shareInfo)
                    .then(loadShareById(shareInfo.id))
        },  
    },
}
export default resolvers


到此,我们就实现了这个简单的GraphQL的Server了。

结语


GraphQL还有很多内容可以探索,使用。比如,如果用Schema构建函数来生成对象类型,可以标记某一个字段为废弃,并给出废弃原因。这样,在版本迭代时,就可以友好的提示到旧版本的使用者,促使其升级到最新的接口,通过某些检测手段,我们也能很轻松的知道旧版本的使用频率,从而方便的让我们在某一个时间彻底删掉这个字段。


如果说GraphQL有什么缺点,那可能就是上手确实没那么容易,而且对于后端同学来说,还是有很多坑要踩的,比如缓存,性能问题等。好在目前的GraphQL的资料已经不像几年前那样的匮乏,不管是官方还是社区,GraphQL可以参考的资源和解决方案都越来越多了。


不管怎样,单纯的对于前端er来说,如果说上一次前端的技术变革是SPA的普及的话,相信当下一次变革到来时,一定有GraphQL的影子。


一些链接





  • graphpack 一个0配置的GraphQL server工具,非常适合初学者去了解GraphQL,并提供了Codepen的方式在线编辑代码,本篇中的示例就是在这个工具的基础上实现的


相关文章
|
6月前
|
缓存 前端开发 API
掌握无限可能:GraphQL在前端开发中的华丽变身
在前端开发领域,GraphQL作为一种革命性的查询语言和API规范,正逐渐崭露头角。本文将介绍GraphQL在前端开发中的应用,探讨其优势和实践经验。通过使用GraphQL,开发者可以轻松构建高效、灵活且可扩展的前端应用,极大地提升开发效率和用户体验。
|
6月前
|
前端开发 数据管理 API
探究GraphQL在前端开发中的实际应用
在如今越来越复杂的前端应用程序中,数据管理变得更加困难,因此GraphQL成为了越来越受欢迎的解决方案。本文将介绍GraphQL在前端开发中的应用,以及它对开发过程所带来的好处。
|
1月前
|
设计模式 SQL 前端开发
使用 GraphQL 和 React 构建动态前端应用
【10月更文挑战第2天】使用 GraphQL 和 React 构建动态前端应用
50 0
|
3月前
|
前端开发 JavaScript
构建前端防腐策略问题之后端配合前端进行GraphQL改造变得不太现实的问题如何解决
构建前端防腐策略问题之后端配合前端进行GraphQL改造变得不太现实的问题如何解决
|
3月前
|
前端开发 API 开发者
JSF与RESTful服务的完美邂逅:如何打造符合现代Web潮流的数据交互新体验
【8月更文挑战第31天】随着互联网技术的发展,RESTful架构风格因其实现简便与无状态特性而在Web服务构建中日益流行。本文探讨如何结合JavaServer Faces (JSF) 和 JAX-RS 构建RESTful API,展示从前端到后端分离的完整解决方案。通过定义资源类、配置 `web.xml` 文件以及使用依赖注入等步骤,演示了在JSF项目中实现RESTful服务的具体过程,为Java开发者提供了实用指南。
40 0
|
3月前
|
缓存 前端开发 安全
Angular 与 GraphQL 强势联合超厉害!现代前端数据获取新范式,开启高效开发新旅程!
【8月更文挑战第31天】在前端开发领域,Angular 与 GraphQL 的结合为数据获取带来了革命性的变化。Angular 凭借其强大的组件化开发模式和依赖注入特性,成为构建大型应用的理想选择。然而,在数据获取上,传统 RESTful API 显得力不从心。这时,GraphQL 出现了,它允许前端精确获取所需数据,避免了数据过度获取或不足的问题。通过一个简单的查询语句,即可一次性获取所需数据,极大地提升了效率。虽然在实际应用中仍需解决缓存和错误处理等问题,但这种结合无疑为现代前端数据获取开辟了新道路,推动技术不断进步。
44 0
|
6月前
|
SQL 前端开发 API
前端需要学GraphQL 吗?
前端需要学GraphQL 吗?
63 2
|
6月前
|
缓存 前端开发 JavaScript
【专栏】GraphQL,Facebook 开发的API查询语言,正在前端开发中崭露头角
【4月更文挑战第27天】GraphQL,Facebook 开发的API查询语言,正在前端开发中崭露头角。它提供强类型系统、灵活查询和实时更新,改善数据获取效率和开发体验。掌握GraphQL涉及学习基础概念、搭建开发环境和实践应用。结合前端框架,利用缓存和批量请求优化性能,与后端协作设计高效API。尽管有挑战,但GraphQL为前端开发开辟新道路,引领未来趋势。一起探索GraphQL,解锁前端无限可能!
94 2
|
6月前
|
缓存 前端开发 API
掌握GraphQL,前端开发无限可能
GraphQL是一种创新性的数据查询和操作语言,它在前端开发中展现出了巨大的应用潜力。本文将介绍GraphQL的基本概念和优势,并探讨其在前端开发中的实际应用,包括数据获取、缓存管理和代码组织等方面。通过学习并掌握GraphQL,前端开发者可以提高开发效率、降低网络请求次数,并且构建出更灵活、可扩展的应用程序。
|
JSON 前端开发 API
如何使用GraphQL进行前端数据交互
如何使用GraphQL进行前端数据交互

热门文章

最新文章

下一篇
无影云桌面