如何使用Node.js构建完整的GraphQL服务器

by Jack R. Scott

杰克·R·斯科特(Jack R.Scott)

如何使用Node.js构建完整的GraphQL服务器 (How to build a full GraphQL server with Node.js)

So, you’re probably thinking — is this just another hullabaloo GraphQL tutorial that is just going to say a lot of big words but not actually help me implement anything?

因此,您可能在想-这只是另一个hullabaloo GraphQL教程,只会说很多大话,但实际上并没有帮助我实现任何东西吗?

✋ The answer is no.

✋答案是否定的。

After reading many guides on how to build a GraphQL server, I realized that none of them completely got me to where I wanted to be. How frustrating.

在阅读了许多有关如何构建GraphQL服务器的指南之后,我意识到没有一个指南可以使我完全适应我想要的目标。 真令人沮丧

It took me way longer than I expected to get up and running.

我花的时间比我预期的长得多。

As such, I am dedicated to giving you a tutorial that actually goes beyond the basics and gives some insights into how to implement a server in the real world. That way everyone can enjoy the truly beautiful feeling of using GraphQL.

因此,我致力于为您提供一个教程,该教程实际上超出了基础知识,并提供了一些有关如何在现实世界中实现服务器的见解。 这样,每个人都可以享受使用GraphQL带来的真正美丽的感觉。

? How do you know this is legit?

您怎么知道这是合法的?

Here is a working version of all code explained in this tutorial. Go ahead, clone it and try it out. I’ll also include another link to the repository at the bottom of this tutorial. Feel free to make pull requests or star the repo so that we can make it as good as possible!

这是本教程中说明的所有代码的有效版本 。 继续,克隆它并尝试一下。 我还将在本教程的底部添加另一个到存储库的链接。 随时提出请求或给回购加注星标,以便我们使它尽可能地好!

? Side note.

边注。

GraphQL is super flexible. It can be implemented in a million different ways — hence why there is so much confusion. Everyone has their own opinion and method of building apps. This is mine. If you have constructive feedback which I can use to improve this tutorial — please share!

GraphQL超级灵活。 可以用一百万种不同的方式来实现它-为什么会有这么多混乱。 每个人都有自己的观点和构建应用程序的方法。 这是我的。 如果您有建设性的反馈意见,可以用来改进本教程,请分享!

Alrighty, let’s do this!

好吧,让我们这样做吧!

一点上下文? (A Little Bit of Context ?‍)

Before I begin, it’s probably a good idea to give some context for the people who don’t already know. GraphQL was created in 2012 by Facebook (thanks again). It was developed as an alternative to the existing REST standard for structuring server queries.

在开始之前,为不认识的人提供一些背景信息可能是一个好主意。 GraphQL由Facebook在2012年创建(再次感谢)。 它被开发为现有REST标准的替代方案 ,用于构建服务器查询。

? What is REST?

什么是REST?

It’s this thing you get when you go to sleep… Gotcha ?

这是你睡觉时得到的东西……好吗?

Honestly, I want to keep this article as succinct as possible. So to help explain, here is a helpful link to an article which explains the REST concept. The reason Facebook created GraphQL as an alternative was because the REST standard had a few key problems:

老实说,我希望这篇文章尽可能简洁。 因此,为了帮助解释,这是指向解释REST概念的文章的有用链接 。 Facebook创建GraphQL作为替代方案的原因是因为REST标准存在一些关键问题:

  1. Fetching complex objects requires multiple calls to the server — laggy.

    提取复杂对象需要多次调用服务器,这很麻烦。
  2. You get more than you ask for. REST generally specifies the shape of the data on the server. Therefore you end up getting a bunch of data you don’t even use.

    您得到的超出了您的要求。 REST通常指定服务器上数据的形状。 因此,您最终会得到甚至不使用的大量数据。
  3. It takes a lot of work to understand exactly what information you are getting back from the server — not very predictable.

    要准确地了解您从服务器获取的信息,需要花费大量的工作-很难预测。

At the time, Facebook had a ton of passionate developers who love testing cool new concepts. So they got some to start working on a new concept which later became GraphQL. They wanted to ask their servers for exactly what they wanted and know that they would get exactly that back. No fluff. ?

当时,Facebook有大量热情的开发人员,他们喜欢测试很酷的新概念。 因此,他们开始研究新概念,后来成为GraphQL。 他们想向服务器询问他们到底想要什么,并且知道他们会得到正确的回报。 没有绒毛。 ?

So… they created a new language that was designed specifically for server queries. This is why GraphQL is described as “A query language for your API”.

因此,…他们创建了一种专门为服务器查询设计的新语言。 这就是为什么GraphQL被描述为“ API的查询语言 ”的原因。

The above is an example of a GraphQL query, as well as an example JSON response. I would describe what’s happening… but it’s pretty self-explanatory.

上面是GraphQL查询的示例以及JSON响应示例。 我将描述发生的事情……但这是不言而喻的。

I’m not going to go much further into “what is GraphQL” because there are plenty of great articles on that topic. However, if you would like some more info, here is an amazing article which gives you a great overview of the concepts and fundamentals of GraphQL.

我将不进一步介绍“什么是GraphQL”,因为有关该主题的文章很多。 但是,如果您需要更多信息, 这是一篇了不起的文章 ,它为您提供了GraphQL的概念和基础的概述。

Let’s move on!

让我们继续!

给我密码! ‍ (Give Me the Code! ?‍?)

Okay okay… Geeh you’re demanding… I’m getting to the code. But before we start, we are going to need to create a new Node.js repository and install a few NPM dependencies.

好吧,好吧... Geeh,您要的是...我正在学习代码。 但是在开始之前,我们将需要创建一个新的Node.js存储库并安装一些NPM依赖项。

? Hot tip: check out Parcel.js for an awesome application bundler which helps you get your development environment sorted in seconds (make sure to set your target to the node environment). Parcel is used by CodeSandbox.

? 热点提示:检查出P arcel.js一个真棒应用程序捆绑它可以帮助你得到你的开发环境,在几秒钟内排序(确保送等你的目标到n ode环境) 。 P arcel由C odeSandbox使用。

P.s.: I am assuming you already know how to set up a Node.js repository. If you don’t, then the concepts in this article may be a little complex for you. You can still follow along to get a general understanding.

附:我假设您已经知道如何设置Node.js存储库。 如果您不这样做,那么本文中的概念可能对您来说有些复杂。 您仍然可以按照以下步骤进行一般了解。

Our NPM dependencies:

我们对NPM的依赖:

  1. apollo-server

    阿波罗服务器

  2. mongoose

    猫鼬

  3. graphql-tools

    graphql工具

Hang on… ? who is Apollo and why do we want his server?

不挂断… ? 谁是阿波罗?为什么我们要他的服务器?

Just to be clear, Apollo is not a person. It is a group of cutting-edge developers who are making awesome strides in the area of GraphQL. They have created a set of production-ready tools and code which is going to make our lives super easy to get started with setting up our GraphQL servers.

需要明确的是,阿波罗不是一个人。 这是一群在GraphQL领域取得了长足进步的前沿开发人员。 他们创建了一套可用于生产的工具和代码,这将使我们的生活变得异常轻松,从而开始设置GraphQL服务器。

Awesome, now that our dependencies are installed, let’s begin by creating an index file as an entry point to our application.

太了不起了,既然已经安装了依赖项,那么我们首先创建一个索引文件作为应用程序的入口点。

? File: src/index.ts

? 文件:s rc/index.ts

I have added a number of comments in the code which will help explain what is going on in the file. Essentially we have created a server and given the server a schema which holds an “empty” type for our Queries (type Query) and an “empty” type for our Mutations (type Mutation).

我在代码中添加了许多注释,这些注释将有助于解释文件中发生的情况。 本质上,我们已经创建了一个服务器,并为服务器提供了一个架构,该架构为我们的查询保留一个“空”类型( type Query ),为我们的突变保留一个“空”类型(类型为type Mutation )。

  • Empty means that it has no properties (yet).

    空意味着它没有属性(尚未)。

Like I said before, I want to make sure this article is as succinct as possible. I am assuming you are a little familiar with how to write basic GraphQL schemas. But if you don’t know, here is a link to how basic schemas work.

就像我之前说过的那样,我想确保这篇文章尽可能简洁。 我假设您对如何编写基本的GraphQL模式有点熟悉。 但是,如果您不知道, 这里是基本模式的工作原理的链接

Next, we are going to set up a database table for our users using mongoose. Our users will have a few basic properties which we can use to query for later on.

接下来,我们将使用猫鼬为用户建立数据库表。 我们的用户将具有一些基本属性,可用于以后查询。

? File: src/common/users/user.model.ts

? 文件:s rc/common/users/user.model.ts

In the above file, we create a user model using mongoose. If you are unfamiliar with mongoose, it is an elegant wrapper which you can use to validate your data as it goes into your database. It also gives us some awesome powers such as virtuals properties, easy querying of data, and more.

在上面的文件中,我们使用猫鼬创建了一个用户模型。 如果您不熟悉mongoose ,它是一个优雅的包装器,您可以使用它来验证数据进入数据库的有效性。 它还为我们提供了一些强大的功能,例如虚拟属性,轻松查询数据等等。

So now we have a model which we can use to save and request data from our database, as well as a server which is running an empty GraphQL server. All we need to do is connect the two together!

因此,现在有了一个可以用来从数据库中保存和请求数据的模型,以及一个正在运行空GraphQL服务器的服务器。 我们需要做的就是两者连接在一起!

To do this, we will create a file which will contain 2 things:

为此,我们将创建一个包含2个内容的文件:

  1. A set of GraphQL types — which tells the client “what” we data we have

    一组GraphQL类型-告诉客户端我们所拥有的数据是“什么”
  2. A matching set of GraphQL resolver functions — which tells the server “how” to do the things that our types describe.

    一组匹配的GraphQL解析程序功能-告诉服务器“如何”执行我们的类型描述的事情。

I am keeping these two code sections in the same file because it made life easier when I was developing.

我将这两个代码节保存在同一文件中,因为这在我开发时使工作变得更轻松。

? File: src/common/users/user.schema.ts

? 文件:s rc/common/users/user.schema.ts

Holy moly! That’s a lot to take in… So let’s break it down, starting with our type definitions:

天哪! 这要花很多钱……所以让我们从类型定义开始对其进行分解:

  • type User { ... }: this is a straight-forward GraphQL type. This is just telling us what the shape of the User is so that the client can query it correctly. You can find more here in the docs.

    type User { ... } :这是简单的GraphQL类型。 这只是告诉我们用户的形状是什么,以便客户端可以正确查询它。 您可以在docs中找到更多信息

  • input UserFilterInput { ... }: similar to a “type” object, an input defines the structure of a complex parameter i.e. something more complex than a String, ID, Int, FLoat or Boolean.

    input UserFilterInput { ... } :类似于“类型”对象,输入定义复杂参数的结构,即比StringIDIntFLoatBoolean更复杂的参数。

  • extend type Query { ... }: so remember when we created our root query type back in the index file? Well, this is referring to that. We are extending that root query and defining the functionality we want to expose to our client. Why do we do it this way? Pfff… It’s not like I want to do it this way (it’s kind-of hacky)… Unfortunately, this was the best way to do it out of a number of poor alternatives. Feel free to give me a better suggestion.

    extend type Query { ... } :还记得我们在索引文件中创建根查询类型时的情况吗? 好吧,这是指。 我们正在扩展该根查询并定义我们要向客户端公开的功能。 我们为什么要这样做? Pfff…这不是我想这样做(有点怪癖)…不幸的是,这是从许多不良选择中最好的方法。 请随时给我一个更好的建议。

  • extend type Mutation { ... }: in the same way that we extend the root query, we are also extending the root mutation.

    extend type Mutation { ... } :以与扩展根查询相同的方式,我们也在扩展根突变。

Now let’s digest what is happening in our user resolvers:

现在,让我们来了解用户解析器中正在发生的事情:

  • Our resolver function names match the names of the fields in both the Query and the Mutation in the type definitions. This helps Apollo know which functions do what.

    我们的解析器函数名称与类型定义中的“ Query和“ Mutation中的字段名称匹配。 这可以帮助Apollo知道哪些功能可以做什么。

  • users: async (_, { filter = {} }) => { ... }: Well, isn’t this line a bit of a mouthful for devs who haven’t seen it before. Don’t worry, it is only stating that for the property users we are assigning an anonymous function which is using async / await to query the database and return some users. Simple ?. The arguments in the function match the arguments in the Apollo server docs which you can find here.

    users: async (_, { filter = {} }) => { .. }:好吧,这条线对以前没有看过的开发人员来说不是那么容易。 别担心,它只是指出了正确的ty us ERS我们指派一个匿名本功能离子是USI 纳克异步/ AW AIT来查询数据库,并返回一些用户。 简单吗? 函数中的参数与您可以找到的Apollo服务器文档中的参数匹配。

  • await User.something(): This syntax is how we use mongoose to either get or save data to the database. It’s super simple once you get your head around it, you can find the docs on mongoose here.

    await User.something() :此语法是我们使用猫鼬将数据获取或保存到数据库的方式。 一旦掌握了它,它就非常简单,您可以在此处找到有关mongoose文档

  • user.toGraph(): This is where most people will get confused. This “toGraph” function comes from our mongoose model file (find it in the model file where it says userSchema.method('toGraph', ...). The reason we need this function is that Mongoose doesn’t return a simple JavaScript object. Rather, it returns a complex object with some random properties that GraphQL doesn’t like. As such, by using the toGraph method, we convert the complex object to a simple object that GraphQL can process.

    user.toGraph() :这是大多数人会感到困惑的地方。 这个“ toGraph”函数来自我们的猫鼬模型文件(在模型文件中找到userSchema.method('toGraph', ... )找到它。我们需要此函数的原因是Mongoose不会返回简单JavaScript相反,它返回具有GraphQL不喜欢的某些随机属性的复杂对象,因此,通过使用toGraph方法,我们将复杂对象转换为GraphQL可以处理的简单对象。

? Wowzers! That was a brain overload.

哇! 那是大脑超负荷。

Don’t worry if you don’t understand all the code straight away. You will be able to clone and experiment with the example repository to your computer once you have finished the tutorial.

如果您不立即了解所有代码,请不要担心。 完成本教程后,您将能够将示例存储库克隆并在计算机上进行实验。

Alrighty! Now let's patch it all together back in the index file…

好吧! 现在,让我们将它们全部打回索引文件中。

? File: src/index.ts

? 文件:s rc/index.ts

All we needed to do was import our type definitions and resolvers, then we added them to our schema. If you go and start your application (hopefully you would have configured a start script i.e. npm start) you should see that your application will open on http://localhost:4000.

我们需要做的就是导入我们的类型定义和解析器,然后将它们添加到架构中。 如果您去启动应用程序(希望您已经配置了一个启动脚本,即npm start ),则应该看到您的应用程序将在http:// localhost:4000上打开。

Troubleshooting: don’t forget to install and start your MongoDB database. Here is a link to an article which shows you how to do this, if you haven’t already.

故障诊断:不要忘记安装和启动您的MongoDB数据库。 这里是一篇文章的链接,该文章向您显示了如何执行此操作(如果尚未执行的话)。

When we navigate to the server in our browser, we will see that Apollo has given us a helpful little tool called a playground. We can use it to test out our GraphQL server. Below is an example of a few queries I tested on our API.

当我们在浏览器中导航到服务器时,我们将看到Apollo给了我们一个有用的小工具,称为Playground。 我们可以使用它来测试我们的GraphQL服务器。 以下是我在API上测试过的一些查询的示例。

You may be wondering; what does query GetAllUsers or mutation AddUser mean?

您可能想知道; query GetAllUsersmutation AddUser是什么意思?

Don’t worry, that is purely there to help you debug your application. They are just names by which you can identify your GraphQL requests. They add no extra functionality to the query or mutation. You can find more information on how to write queries and mutation here.

不用担心,它纯粹是在帮助您调试应用程序。 它们只是您可以识别 GraphQL请求的名称。 它们不为查询或变异添加任何额外功能。 您可以在此处找到有关如何编写查询和变异的更多信息。

?‍ Hey Jack, there is still one thing I’m still unsure of. What is the difference between Queries and Mutations?

嗨, 杰克,我仍然不确定一件事。 什么是Q ueries和M utations之间的区别

Great question! I had a feeling you would ask. In order to truly understand this, we need to look at what is happening under the hood of our server. Many people suggest that Queries are the equivalent of a GET request. Mutations are for all others i.e. POST, PUT, PATCH, and DELETE but this isn’t exactly true.

好问题! 我有一种感觉,你会问。 为了真正理解这一点,我们需要查看服务器内部发生的情况。 许多人建议查询等同于GET请求。 突变适用于所有其他PUT ,例如POSTPUTPATCHDELETE但这不是真的。

Let’s look at an example of 2 requests to our GraphQL server from our Apollo GraphQL playground — which comes with Apollo Server straight out of the box.

让我们看一个示例,该示例从Apollo GraphQL游乐场向GraphQL服务器发出2个请求,该请求随即提供。

As you can see, both the query and the mutation requests are POST requests. The reason for this is that they both have the ability to pass variables into their requests e.g. users (limit: $maxUsers) { ... }.

如您所见, querymutation请求都是POST请求。 这样做的原因是,他们俩都有能力将变量传递到他们的请求中,例如users (limit: $maxUsers) { ... }

The real difference between the two is that:

两者之间的真正区别在于:

  1. Queries are executed in parallel.

    查询是并行执行的。
  2. Mutations are executed in series.

    变异是连续执行的。

That way queries can be executed fast and mutations can be executed reliably. Thanks to Prisma for the help on that one.

这样,查询可以快速执行,并且变异可以可靠地执行。 感谢Prisma在这一方面的帮助。

⏰时间来一个水平! (⏰ Time to Take it Up a Level!)

So we’ve done a pretty good job so far, we know how to:

因此,到目前为止,我们做得很好,我们知道如何:

  • ✅ Create a basic server.

    ✅创建一个基本服务器。
  • ✅ Create a mongoose schema which validates our database data.

    ✅创建一个猫鼬模式来验证我们的数据库数据。
  • ✅ Define our GraphQL data structure on the server using type definitions.

    using使用类型定义在服务器上定义我们的GraphQL数据结构。
  • ✅ Connect our mongoose schema to the GraphQL server using resolvers.

    using使用解析器将我们的猫鼬模式连接到GraphQL服务器。
  • ✅ Make some queries and mutations through the Apollo playground.

    through在阿波罗游乐场进行一些查询和更改。

I’d say that’s a fair shake of the sauce bottle — Kevin ’07. But there are still a few things missing…

我想说那是酱油瓶的一个很好的调料-凯文'07。 但是仍然缺少一些东西……

? What about when we have related database items, how do we deal with that?

当我们拥有相关的数据库项时,该如何处理呢?

It’s actually pretty simple, let’s do it!

实际上很简单,让我们开始吧!

First off, we will pretend that every user is related/attached to a single workspace. In this situation, we might want to request information from the workspace related to the user, at the same time that we ask for information about that user.

首先,我们将假装每个用户都关联/附加到单个工作空间。 在这种情况下,我们可能希望从工作空间中请求与该用户相关的信息,同时又要求该用户的信息。

To do this, we first have to define a new mongoose model. We will use it to save and request workspaces from the database.

为此,我们首先必须定义一个新的猫鼬模型。 我们将使用它来从数据库保存和请求工作空间。

? File: src/common/workspace/workspace.model.ts

? 文件:s rc/common/workspace/workspace.model.ts

Similar to the way we created our users, we will also make a schema file for our workspaces so that they can be queried on their own as well.

与创建用户的方式类似,我们还将为工作区创建一个模式文件,以便也可以自行查询它们。

? File: src/common/workspace/workspace.schema.ts

? 文件:s rc/common/workspace/workspace.schema.ts

Sweet, now we just need to update the index file so it recognizes our workspace GraphQL schema and resolvers. Note: to merge resolvers, we need to use lodash’s merge function which deeply merges two objects together.

亲爱的,现在我们只需要更新索引文件,以便它可以识别我们的工作区GraphQL模式和解析器。 注意:要合并解析器,我们需要使用lodash的merge函数,它将两个对象深度合并在一起。

? File: src/index.ts

? 文件:s rc/index.ts

Once you’ve implemented the above code, you would be able to create and query workspace’s just like we did with our users! But that’s not much cooler than before. What will be really cool is when we query data about a workspace “through” the user object.

一旦实现了以上代码,就可以像创建用户一样创建和查询工作区! 但这并没有以前那么酷。 真正酷的是当我们“通过”用户对象查询有关工作空间的数据时。

To do that, we can use a cool feature of mongoose which allows us to reference database items to each other (e.g. the workspace to the user). These references stored as special ObjectId types. Go ahead and update our User model so that it can save the id of a workspace to our users.

为此,我们可以使用猫鼬的一个很酷的功能,它允许我们相互引用数据库项(例如,用户的工作区)。 这些引用存储为特殊的ObjectId类型。 继续并更新我们的用户模型,以便可以将工作区的ID保存给我们的用户。

? File: src/common/user/user.model.ts

? 文件:s rc/common/user/user.model.ts

Lastly, we need to update our user’s schema file so that Apollo knows how to resolve our (nested) reference to the user’s workspace.

最后,我们需要更新用户的架构文件,以便Apollo知道如何解决对用户工作区的(嵌套)引用。

? File: src/common/user/user.schema.ts

? 文件:s rc/common/user/user.schema.ts

Let’s take a look at the 2 main changes that we just made in the user schema file:

让我们看一下我们刚刚在用户模式文件中进行的2个主要更改:

  1. The type User now has 2 extra properties: workspaceId (which matches the Mongoose model) and workspace (which will be where we put the workspace object when we query for it).

    type User现在具有2个额外的属性: workspaceId (与Mongoose模型匹配)和workspace (将在我们查询工作空间对象时将其放置在此处)。

  2. There is now a property called User in our resolvers. This is one of my personal favorite parts of GraphQL as it lets you resolve individual properties of a type. In the example above, we resolve the workspace property by taking the workspaceId of the user and then using Mongoose to fetch it from the database for us. This is just the same as we were doing for regular Query resolvers but this time it is a nested object.

    现在,我们的解析器中有一个名为User的属性。 这是GraphQL我个人最喜欢的部分之一,因为它可以让您解析类型的单个属性。 在上面的示例中,我们通过获取用户的工作区ID来解析workspace属性,然后使用Mongoose从数据库中为我们获取它。 这与我们对常规查询解析器所做的相同,但是这次它是一个嵌套对象。

Now, we can go back to our playground and start playing around with making and querying both users and workspace’s together.

现在,我们可以回到操场,开始一起制作和查询用户以及工作空间。

Hell yeah! We have the essentials covered for what you could turn into a fully working server.

真是的! 我们为您提供了一些必要的知识,您可以将它们变成可以正常工作的服务器。

? Holy moly! You’re up and running with GraphQL!

天哪! 您已启动并运行GraphQL!

授权吗? (Authorization ?️‍)

So currently, we have a pretty good GraphQL API. But there is still a problem: there are no restrictions on who can access our data! To fix this, we need to add authentication and authorization.

因此,目前,我们有一个相当不错的GraphQL API。 但是仍然存在一个问题:谁可以访问我们的数据没有任何限制! 要解决此问题,我们需要添加身份验证和授权。

✋ Hang on… authentication and authorization are not the same?

✋等一下... 认证授权不一样吗?

This is a common misconception, but an important one to understand as it will help you build better APIs:

这是一个常见的误解,但很重要,需要理解,因为它将帮助您构建更好的API:

  • Authentication refers to identifying the person who is requesting info i.e. working out which user is sending a request to the API.

    认证是指识别请求信息的人,即确定哪个用户正在向API发送请求。

  • Authorization refers to the permissions available to that requestor i.e. which roles the user has and is that role sufficient enough to allow the request.

    授权是指可用于该请求者的权限,即用户具有哪些角色,并且该角色足以允许请求。

? So then, how do we implement that?

那么,我们如何实现呢?

Another excellent question, you are a really curious person! Well, there are unfortunately many ways to do this depending on how you might want your app to work. For example:

另一个很好的问题,你真是一个好奇的人! 好吧,不幸的是,有许多方法可以执行此操作,具体取决于您希望应用程序如何工作。 例如:

  • You might only want users to sign up with GitHub auth as opposed to signing up with email and password.

    您可能只希望用户使用GitHub auth进行注册,而不是使用电子邮件和密码进行注册。
  • You might have 3 different user roles as opposed to 100 fine grained user roles.

    您可能有3个不同的用户角色,而不是100个细粒度的用户角色。
  • There might be no users at all, you’re whole app could be anonymously used.

    可能根本没有用户,您可以匿名使用整个应用程序。

In any case, the way you implement authentication and authorization is up to you. But if you would like a guide on where to start, here is a link to an awesome article by Prisma which helps you get started on adding auth to your API.

无论如何,实施身份验证和授权的方式取决于您。 但是,如果您想从哪里开始, 这里有指向 Prisma的一篇很棒的文章的链接 ,可以帮助您开始向API添加身份验证。

To make it a little easier, I have also added some basic authentication to our demo repository which you can browse and check out. Feel free to improve the repository with a better auth example and submit a pull request!

为了使操作更简单,我还向我们的演示存储库添加了一些基本身份验证,您可以浏览并签出。 随时使用更好的auth示例来改进存储库并提交请求请求!

~ Here is a link to the demo GraphQL repository ~

这是演示GraphQL存储库的链接

? Hot damn! We managed to make a GraphQL server! Go you!

该死的! 我们设法制作了GraphQL服务器! 去吧!

If you enjoyed this article, please give it a few claps (you can leave up to 50) or you can comment if you have any questions, I’ll do my best to answer! ?

如果您喜欢这篇文章,请给它鼓掌 (最多可以保留50条),或者如果您有任何问题可以发表评论 ,我会尽力回答! ?

Follow me on Twitter.

Twitter上关注我。

Thanks!

谢谢!

More posts by Jack Scott.

杰克·斯科特(Jack Scott)的更多帖子。

翻译自: https://www.freecodecamp.org/news/graphql-zero-to-production-a7c4f786a57b/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值