Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Okay, let’s see what’s going on here. The `actors` connection now has a more

Don’t worry. In order to use Relay, you don’t have to understand the reasons why the structure is designed this way but rest assured that [it makes a lot of sense](https://relay.dev/graphql/connections.htm).

![](/connections-edges-nodes-in-relay-758d358aa4c7/imgs/0*sPafc6eXHJvRSJhZ.png)
![](/connections-edges-nodes-in-relay-758d358aa4c7/imgs/0-sPafc6eXHJvRSJhZ.png)

Lastly, we also notice the first: 10 parameter on the actors field. This gives us a way to [paginate](https://en.wikipedia.org/wiki/Pagination) over the entire list of related actors. In this case we’re taking the first 10 actors (nodes). In the same way we could additionally specify the after parameter which allows us to skip a certain amount of nodes.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ export default graphql(

In your local development setup, where the React app is loaded from [`http://localhost:3000`](http://localhost:3000) and the GraphQL server is serving at [`http://localhost:4000`](http://localhost:4000)/graphql, you’ll now get an access control error if you’re trying to run the app:

![](/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d/imgs/1*ZbsVGATAeIp5iU2504VP2A.png)
![](/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d/imgs/1-ZbsVGATAeIp5iU2504VP2A.png)

What exactly is the issue when CORS is not enabled? Well, CORS is in fact a _specification_ for a communication flow between client (a browser) and server. In some situations, this flow requires the server to process HTTP [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS) requests as can be seen from this flowchart:

![The CORS flow might required additional HTTP requests with the [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS) method ([source](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing#/media/File:Flowchart_showing_Simple_and_Preflight_XHR.svg))](/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d/imgs/1*m6QGz5tXtLt7uVapNCpBEw.png)_The CORS flow might required additional HTTP requests with the [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS.png) method ([source](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing#/media/File:Flowchart_showing_Simple_and_Preflight_XHR.svg))_
![The CORS flow might required additional HTTP requests with the [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS) method ([source](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing#/media/File:Flowchart_showing_Simple_and_Preflight_XHR.svg))](/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d/imgs/1-m6QGz5tXtLt7uVapNCpBEw.png)_The CORS flow might required additional HTTP requests with the [OPTIONS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS.png) method ([source](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing#/media/File:Flowchart_showing_Simple_and_Preflight_XHR.svg))_

The problem is that neither `express-graphql` nor `apollo-server` accept HTTP requests other than GET and POST — which is why the request fails in our scenario. This is also indicated by the error message we saw in the console: `OPTIONS [http://localhost:4000](http://localhost:4000) 405 (Method not allowed)`.

Expand All @@ -141,7 +141,7 @@ Luckily, the solution is very simple. As `express-graphql` and `apollo-server` a

Uncommenting [line 23](https://github.com/nikolasburk/graphql-cors-example/blob/master/server/index.js#L23) in `server.js` will enable the cors middleware for your express server: `app.use(cors())`. Having the middleware enabled ensures your express server sets the proper HTTP header, enabling your React app to load data from it:

![Using the [cors](/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d/imgs/cors) middleware, the server sets the correct HTTP header enabling cross-origin resource sharing](/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d/imgs/1*LnVsDQuQtSl-Wt-m6DfO5g.png)_Using the [cors](https://github.com/expressjs/cors) middleware, the server sets the correct HTTP header enabling cross-origin resource sharing_
![Using the [cors](/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d/imgs/cors) middleware, the server sets the correct HTTP header enabling cross-origin resource sharing](/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d/imgs/1-LnVsDQuQtSl-Wt-m6DfO5g.png)_Using the [cors](https://github.com/expressjs/cors) middleware, the server sets the correct HTTP header enabling cross-origin resource sharing_

## Summary

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ type Post {
```
This is what it should look like in your terminal:

![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0*t5Y1tsH07bEQHbrB.png)
![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0-t5Y1tsH07bEQHbrB.png)

Note that you can now manage this project in the Graphcool Console. If you want to manage it locally, you can use the project file `project.graphcool` to make local changes to the schema and then apply them by calling `graphcool push`.

Expand Down Expand Up @@ -220,7 +220,7 @@ Awesome, you’re now ready to use Relay in your app 🚀

> **Note**: If you lose the endpoint for your GraphQL API, you can always find it in the Graphcool Console (by clicking in _ENDPOINTS_-button on the bottom-left) or use the graphcool endpoints command in the same directory where the project file project.graphcool is located:

![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0*KQLRnImerQRjALS5.png)
![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0-KQLRnImerQRjALS5.png)

## 3. Displaying all Posts

Expand Down Expand Up @@ -333,7 +333,7 @@ yarn start
```
This will open up a browser and load the app from `http://localhost:3000` where you'll now see two lovely pigs:

![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0*QelKIjXtM12d3kAe.png)
![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0-QelKIjXtM12d3kAe.png)

### Load Data from Server

Expand Down Expand Up @@ -616,7 +616,7 @@ Notice that you’ll have to switch the Playground mode from **Simple** to **Rel

Then click the _Play_-button and select each of these mutations exactly once:

![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0*iPceJCV7B-ri4upn.png)
![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0-iPceJCV7B-ri4upn.png)

> **Note**: You can also use the Data Browser to add some post items.

Expand All @@ -626,7 +626,7 @@ Go ahead and run `yarn start` to see what the app currently looks like - you sho

By the way, if you’re curios to see what the actual query looked like that the `QueryRenderer` composed for you and that was sent over to the server, you can inspect the _Networking_-tab of your browser's dev tools:

![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0*A92lc0WjBQD120DC.png)
![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0-A92lc0WjBQD120DC.png)

## 4. Adding and Deleting Posts

Expand Down Expand Up @@ -734,7 +734,7 @@ import { Link } from 'react-router'
```
Pressing the `Link` element in the app will now trigger the `CreatePage` to appear on the screen. You can run the app again and you should see everything as before, plus the **+ New Post**-button on the top right. Press it to convince yourself that it actually displays the `CreatePage` component:

![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0*h_JXfmCfcMYpbO__.png)
![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0-h_JXfmCfcMYpbO__.png)

### Creating new Posts

Expand Down Expand Up @@ -848,7 +848,7 @@ So, in `optimisticUpdater`, you're simply creating the `newPost` yourself based

For the `updater` you can make use of the actual server response to update the cache. With `getRootField` and `getLinkedRecord` you get access to the payload of the mutation that you specified on top of the file:

![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0*lWBTpLYdMBLe7BvS.png)
![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0-lWBTpLYdMBLe7BvS.png)

Next you need to actually use this mutation in `CreatePage.js`. The only problem left right now is that in `CreatePage`, you don't have access to the `viewerId` at the moment - but it's a required argument for the mutation. At this point, you _could_ use `react-router` and simply pass the `viewerId` from the `ListPage` on to the `CreatePage` component. However, we want to make proper use of Relay and each component should be responsible for its own data dependencies.

Expand Down Expand Up @@ -938,7 +938,7 @@ relay-compiler --src ./src --schema ./schema.graphql
```
That’s it, you can now go ahead and add a new post through the UI of your app! How about these musical fellahs right here?

![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0*p_mSrJU2L90IXDSi.jpg)
![](/getting-started-with-relay-modern-46f8de6bd6ec/imgs/0-p_mSrJU2L90IXDSi.jpg)

### Deleting Posts

Expand Down
10 changes: 5 additions & 5 deletions apps/blog/content/blog/graphql-eu-18-eiw8bishe2di/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ In the past 12 months, we have organized two major GraphQL conferences: GraphQL

At last year's GraphQL Europe conference, 300 GraphQL enthusiasts came together to discuss the latest topics of the GraphQL ecosystem and share their own experiences with other attendees. We were especially excited to welcome many community members that flew over to Europe from the US and from Australia.

![](/graphql-eu-18-eiw8bishe2di/imgs/1*f3CIuLP_Lr3Q0UYNsP5lvQ.jpeg)
![](/graphql-eu-18-eiw8bishe2di/imgs/1-f3CIuLP_Lr3Q0UYNsP5lvQ.jpeg)

Next to fruitful discussions with other developers, the conference offered a broad range of talks from various GraphQL experts.

Expand Down Expand Up @@ -67,7 +67,7 @@ The range of topics to be presented at the conference will be extremely diverse.

Here's a quick selection of a few talks to be presented at the conference, you can find the entire schedule on the [website](https://www.graphql-europe.org#schedule).

![](/graphql-eu-18-eiw8bishe2di/imgs/1*-iELVZWzvAgEaKZlkNU6ZA.png)
![](/graphql-eu-18-eiw8bishe2di/imgs/1--iELVZWzvAgEaKZlkNU6ZA.png)

### Transpiling GraphQL instead of writing customized server code

Expand All @@ -83,23 +83,23 @@ by **[Jon Wong](https://twitter.com/jnwng)** (Frontend Infrastructure Engineer @

Supercharge your GraphQL development with the linting, formatting, and static analysis tools you need to write cleaner and more reliable GraphQL.

![](/graphql-eu-18-eiw8bishe2di/imgs/1*AN2VR8MNLpLeNzUOEGbCJA.png)
![](/graphql-eu-18-eiw8bishe2di/imgs/1-AN2VR8MNLpLeNzUOEGbCJA.png)

### Fundamental Properties of the GraphQL Language

by **[Olaf Hartig](https://twitter.com/olafhartig)** (Assistant Professor for CS @ Linköping University)

This talk presents a formal study of the GraphQL language. After a gentle introduction to the typical problems considered in such studies, I highlight our findings regarding these problems for the case of GraphQL. As a bonus, I present a solution to avoid producing overly large query results.

![](/graphql-eu-18-eiw8bishe2di/imgs/1*_QMKg1HIi96OtzMMOtoajQ@2x.png)
![](/graphql-eu-18-eiw8bishe2di/imgs/1-_QMKg1HIi96OtzMMOtoajQ@2x.png)

### 2 Fast 2 Furious: migrating Medium’s codebase without slowing down

by **[Sasha Solomon](https://twitter.com/sachee)** (Tech Lead @ Medium)

After 5 years, we’re building the next generation infrastructure at Medium with GraphQL and we’re doing it without slowing product development and we’re incrementally gaining benefits from the new system. See how we take advantage of GraphQL to enable widespread yet gradual architectural change!

![](/graphql-eu-18-eiw8bishe2di/imgs/1*kKq-QXjiDhsDi82ZK8OX8w.png)
![](/graphql-eu-18-eiw8bishe2di/imgs/1-kKq-QXjiDhsDi82ZK8OX8w.png)

### Teaching GraphQL

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ A resolver function takes four arguments (in that order):

Here is an overview of the execution process of a simple GraphQL query and the invocations of the belonging resolvers. Because the resolution of the _2nd resolver level_ is trivial, there is no need to actually implement these resolvers — their return values are automatically inferred by GraphQL.js:

![](/graphql-server-basics-demystifying-the-info-argument-in-graphql-resolvers-6f26249f613a/imgs/1*2UStyS7v3NIZKl2cLsBtYA.png)
![](/graphql-server-basics-demystifying-the-info-argument-in-graphql-resolvers-6f26249f613a/imgs/1-2UStyS7v3NIZKl2cLsBtYA.png)

_Overview of the `parent` and `args` argument in the GraphQL resolver chain_

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ A key thing to understand about GraphQL is that it’s actually agnostic to the

> The following section is mainly about Express.js and its concept of middleware that’s used for GraphQL libraries like `express-graphql` and `apollo-server`. **If you’re already familiar with Express, you can skip ahead to the next section.**

![Comparison of [express](https://expressjs.com), [hapi](https://hapijs.com/), [koa](http://koajs.com/) and [sail](https://sailsjs.com/) on [npm trends](http://www.npmtrends.com/)](/graphql-server-basics-the-network-layer-51d97d21861/imgs/1*6ERw4Znf6UYou_epNUutRA.png)_Comparison of [express](https://expressjs.com), [hapi](https://hapijs.com/), [koa](http://koajs.com/) and [sail](https://sailsjs.com/) on [npm trends](http://www.npmtrends.com/)_
![Comparison of [express](https://expressjs.com), [hapi](https://hapijs.com/), [koa](http://koajs.com/) and [sail](https://sailsjs.com/) on [npm trends](http://www.npmtrends.com/)](/graphql-server-basics-the-network-layer-51d97d21861/imgs/1-6ERw4Znf6UYou_epNUutRA.png)_Comparison of [express](https://expressjs.com), [hapi](https://hapijs.com/), [koa](http://koajs.com/) and [sail](https://sailsjs.com/) on [npm trends](http://www.npmtrends.com/)_

[Express.js](https://expressjs.com/) is by far the [most popular](http://www.npmtrends.com/express-vs-hapi-vs-koa-vs-sails) JavaScript web framework. It shines thanks to its simplicity, flexibility and performance.

Expand All @@ -47,7 +47,7 @@ app.listen(3000)
```
After executing this script with [Node.js](https://nodejs.org/en/), you can access the website on `http://localhost:3000` in your browser:

![](/graphql-server-basics-the-network-layer-51d97d21861/imgs/1*0ZgAAtT0Zm-Kc63SNeT5Ew.png)
![](/graphql-server-basics-the-network-layer-51d97d21861/imgs/1-0ZgAAtT0Zm-Kc63SNeT5Ew.png)

You can easily add more _endpoints_ (also called [_routes_](https://expressjs.com/en/guide/routing.html)) to your server’s API:

Expand Down Expand Up @@ -184,7 +184,7 @@ app.listen(4000)
```
## `graphql-yoga`: The easiest way to build a GraphQL server

![](/graphql-server-basics-the-network-layer-51d97d21861/imgs/1*yIYI_iNabiNS_7uuzFVJDQ.png)
![](/graphql-server-basics-the-network-layer-51d97d21861/imgs/1-yIYI_iNabiNS_7uuzFVJDQ.png)

### Removing friction when building GraphQL servers

Expand Down Expand Up @@ -222,7 +222,7 @@ Note that a `GraphQLServer` can either be instantiated using a ready instance of

Note that `graphql-yoga` also has built-in support for [`graphql-playground`](https://github.com/graphcool/graphql-playground). With the code above you can open the Playground at `http://localhost:4000`:

![](/graphql-server-basics-the-network-layer-51d97d21861/imgs/1*dMyX0jnoKvhYAa0cgSqenQ.png)
![](/graphql-server-basics-the-network-layer-51d97d21861/imgs/1-dMyX0jnoKvhYAa0cgSqenQ.png)

`graphql-yoga` also features a simple API for GraphQL subscriptions out-of-the-box, built on top of the [`graphql-subscriptions`](https://github.com/apollographql/graphql-subscriptions) and [`ws-subscriptions-transport`](https://github.com/apollographql/subscriptions-transport-ws) package. You can check out how it works in this [straightforward example](https://github.com/graphcool/graphql-yoga/tree/master/examples/subscriptions).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ const UserType = new GraphQLObjectType({

Considering our query from above, let’s understand how it’s executed and data is collected. The query in total contains three fields: `user` (the _root field_), `id` and `name`. This means that when the query arrives at the server, the server needs to call three resolver functions — one per field. Let’s walk through the execution flow:

![](/graphql-server-basics-the-schema-ac5e2950214e/imgs/1*_fQh0zWBlDG1OJ-FbMnWcw.png)
![](/graphql-server-basics-the-schema-ac5e2950214e/imgs/1-_fQh0zWBlDG1OJ-FbMnWcw.png)

1. The query arrives at the server.
1. The server invokes the resolver for the root field `user` — let’s assume `fetchUserById` returns this object: `{ "id": "abc", "name": "Sarah" }`
Expand Down
Loading
Loading