Add absinthe-socket-link
and send all GraphQL via a Phoenix channel.
This commit is contained in:
parent
be3f4203d2
commit
8a4ed2c727
12 changed files with 173 additions and 42 deletions
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"*.js": "javascriptreact"
|
||||||
|
}
|
||||||
|
}
|
32
README.md
32
README.md
|
@ -1,23 +1,15 @@
|
||||||
# Client-side GraphQL
|
# Extra for experts
|
||||||
|
|
||||||
So, a GraphQL API isn't much use without the ability to use it from the browser,
|
Our little React app is pretty neat. When it loads it queries the server for a
|
||||||
so here's where we implement the faces gallery as a client-side app. Whilst
|
list of people and shows their faces and allows us to run a mutation to add a
|
||||||
it's possible to do progressive enhancement I've removed all functionality from
|
new person to our list.
|
||||||
the faces controller to prove that all the data loading and changing is
|
|
||||||
happening via GraphQL.
|
|
||||||
|
|
||||||
I've used [React](https://reactjs.org/) and [Apollo
|
There's only one problem. What happens if someone else comes along and adds a
|
||||||
client](https://www.apollographql.com/client) via
|
face to our gallery? Our client won't know that the data has changed and will
|
||||||
[react-apollo](https://www.apollographql.com/docs/react/).
|
just keep showing us stale data. This is where [GraphQL
|
||||||
|
Subscriptions](http://graphql.org/blog/subscriptions-in-graphql-and-relay/) come
|
||||||
|
in.
|
||||||
|
|
||||||
Things to look at:
|
Absinthe has built-in support for subscriptions and since we're using Phoenix we
|
||||||
|
have a well-tested channel implementation to run it over (Absinthe can use it's
|
||||||
* `assets/js/app.js`
|
own socket protocol too, if you're not running in Phoenix).
|
||||||
* `assets/js/components/Gallery.js`
|
|
||||||
* `assets/js/components/AddFace.js`
|
|
||||||
* `assets/js/queries/list_people.js`
|
|
||||||
* `assets/js/queries/import_person.js`
|
|
||||||
|
|
||||||
[Demo](http://localhost:4000)
|
|
||||||
|
|
||||||
Next, let's flip over to `step-5` to see some magic.
|
|
||||||
|
|
7
assets/js/absinthe-socket-link.js
Normal file
7
assets/js/absinthe-socket-link.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import * as AbsintheSocket from "@absinthe/socket";
|
||||||
|
import { createAbsintheSocketLink } from "@absinthe/socket-apollo-link";
|
||||||
|
import { Socket as PhoenixSocket } from "phoenix";
|
||||||
|
|
||||||
|
export default createAbsintheSocketLink(AbsintheSocket.create(
|
||||||
|
new PhoenixSocket("ws://localhost:4000/socket")
|
||||||
|
));
|
|
@ -1,11 +1,9 @@
|
||||||
import { ApolloClient } from 'apollo-client';
|
import { ApolloClient } from "apollo-client";
|
||||||
import { HttpLink } from 'apollo-link-http';
|
import { InMemoryCache } from "apollo-cache-inmemory";
|
||||||
import { InMemoryCache } from 'apollo-cache-inmemory';
|
import absintheSocketLink from "./absinthe-socket-link";
|
||||||
|
|
||||||
const client = new ApolloClient({
|
const client = new ApolloClient({
|
||||||
link: new HttpLink({
|
link: absintheSocketLink,
|
||||||
uri: "/api"
|
|
||||||
}),
|
|
||||||
cache: new InMemoryCache(),
|
cache: new InMemoryCache(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"watch": "brunch watch --stdin"
|
"watch": "brunch watch --stdin"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@absinthe/socket-apollo-link": "^0.1.11",
|
||||||
"apollo-client-preset": "^1.0.8",
|
"apollo-client-preset": "^1.0.8",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
"graphql": "^0.13.2",
|
"graphql": "^0.13.2",
|
||||||
|
|
106
assets/yarn.lock
106
assets/yarn.lock
|
@ -2,6 +2,53 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@absinthe/socket-apollo-link@^0.1.11":
|
||||||
|
version "0.1.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/@absinthe/socket-apollo-link/-/socket-apollo-link-0.1.11.tgz#8dde213db3cf6e73419693c409ba00c96214a0e6"
|
||||||
|
dependencies:
|
||||||
|
"@absinthe/socket" "0.1.10"
|
||||||
|
apollo-link "1.0.0"
|
||||||
|
babel-runtime "6.26.0"
|
||||||
|
flow-static-land "0.2.8"
|
||||||
|
graphql "0.11.7"
|
||||||
|
zen-observable "0.6.0"
|
||||||
|
|
||||||
|
"@absinthe/socket@0.1.10":
|
||||||
|
version "0.1.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@absinthe/socket/-/socket-0.1.10.tgz#657f7b32cd6161bdc20b28c1377dc3596ea25432"
|
||||||
|
dependencies:
|
||||||
|
"@jumpn/utils-array" "0.3.4"
|
||||||
|
"@jumpn/utils-composite" "0.5.0"
|
||||||
|
"@jumpn/utils-graphql" "0.5.3"
|
||||||
|
babel-runtime "6.26.0"
|
||||||
|
phoenix "1.3.0"
|
||||||
|
zen-observable "0.6.0"
|
||||||
|
|
||||||
|
"@jumpn/utils-array@0.3.4":
|
||||||
|
version "0.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jumpn/utils-array/-/utils-array-0.3.4.tgz#fb4310120108f659dab54075ef93abc56137de5e"
|
||||||
|
dependencies:
|
||||||
|
babel-polyfill "6.26.0"
|
||||||
|
babel-runtime "6.26.0"
|
||||||
|
flow-static-land "0.2.7"
|
||||||
|
|
||||||
|
"@jumpn/utils-composite@0.5.0":
|
||||||
|
version "0.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jumpn/utils-composite/-/utils-composite-0.5.0.tgz#83580d470d0042f756889d2d057c2675fa1ebac6"
|
||||||
|
dependencies:
|
||||||
|
"@jumpn/utils-array" "0.3.4"
|
||||||
|
babel-polyfill "6.26.0"
|
||||||
|
babel-runtime "6.26.0"
|
||||||
|
fast-deep-equal "1.0.0"
|
||||||
|
flow-static-land "0.2.8"
|
||||||
|
|
||||||
|
"@jumpn/utils-graphql@0.5.3":
|
||||||
|
version "0.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@jumpn/utils-graphql/-/utils-graphql-0.5.3.tgz#a7b41b0bec34d8dc1873981be0a718190673f430"
|
||||||
|
dependencies:
|
||||||
|
babel-runtime "6.26.0"
|
||||||
|
graphql "0.11.7"
|
||||||
|
|
||||||
"@types/async@2.0.47":
|
"@types/async@2.0.47":
|
||||||
version "2.0.47"
|
version "2.0.47"
|
||||||
resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.47.tgz#f49ba1dd1f189486beb6e1d070a850f6ab4bd521"
|
resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.47.tgz#f49ba1dd1f189486beb6e1d070a850f6ab4bd521"
|
||||||
|
@ -163,6 +210,13 @@ apollo-link-http@^1.3.1:
|
||||||
apollo-link "^1.2.1"
|
apollo-link "^1.2.1"
|
||||||
apollo-link-http-common "^0.2.3"
|
apollo-link-http-common "^0.2.3"
|
||||||
|
|
||||||
|
apollo-link@1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.0.0.tgz#3d334285789c217f95712ebce434d56ce7f3e991"
|
||||||
|
dependencies:
|
||||||
|
apollo-utilities "^0.2.0-beta.0"
|
||||||
|
zen-observable "^0.6.0"
|
||||||
|
|
||||||
apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.1:
|
apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.1.tgz#c120b16059f9bd93401b9f72b94d2f80f3f305d2"
|
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.1.tgz#c120b16059f9bd93401b9f72b94d2f80f3f305d2"
|
||||||
|
@ -171,6 +225,10 @@ apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.1:
|
||||||
apollo-utilities "^1.0.0"
|
apollo-utilities "^1.0.0"
|
||||||
zen-observable-ts "^0.8.6"
|
zen-observable-ts "^0.8.6"
|
||||||
|
|
||||||
|
apollo-utilities@^0.2.0-beta.0:
|
||||||
|
version "0.2.0-rc.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-0.2.0-rc.3.tgz#7bd93be0f587f20c5b46e21880272e305759fdc2"
|
||||||
|
|
||||||
apollo-utilities@^1.0.0, apollo-utilities@^1.0.11:
|
apollo-utilities@^1.0.0, apollo-utilities@^1.0.11:
|
||||||
version "1.0.11"
|
version "1.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.11.tgz#cd36bfa6e5c04eea2caf0c204a0f38a0ad550802"
|
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.11.tgz#cd36bfa6e5c04eea2caf0c204a0f38a0ad550802"
|
||||||
|
@ -708,6 +766,14 @@ babel-plugin-transform-strict-mode@^6.24.1:
|
||||||
babel-runtime "^6.22.0"
|
babel-runtime "^6.22.0"
|
||||||
babel-types "^6.24.1"
|
babel-types "^6.24.1"
|
||||||
|
|
||||||
|
babel-polyfill@6.26.0:
|
||||||
|
version "6.26.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
|
||||||
|
dependencies:
|
||||||
|
babel-runtime "^6.26.0"
|
||||||
|
core-js "^2.5.0"
|
||||||
|
regenerator-runtime "^0.10.5"
|
||||||
|
|
||||||
babel-preset-es2015@^6.24.1:
|
babel-preset-es2015@^6.24.1:
|
||||||
version "6.24.1"
|
version "6.24.1"
|
||||||
resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
|
resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939"
|
||||||
|
@ -787,7 +853,7 @@ babel-register@^6.26.0:
|
||||||
mkdirp "^0.5.1"
|
mkdirp "^0.5.1"
|
||||||
source-map-support "^0.4.15"
|
source-map-support "^0.4.15"
|
||||||
|
|
||||||
babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0:
|
babel-runtime@6.26.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0:
|
||||||
version "6.26.0"
|
version "6.26.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1754,6 +1820,10 @@ extsprintf@^1.2.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||||
|
|
||||||
|
fast-deep-equal@1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
|
||||||
|
|
||||||
fast-deep-equal@^1.0.0:
|
fast-deep-equal@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
|
||||||
|
@ -1856,6 +1926,14 @@ flat-cache@^1.2.1:
|
||||||
graceful-fs "^4.1.2"
|
graceful-fs "^4.1.2"
|
||||||
write "^0.2.1"
|
write "^0.2.1"
|
||||||
|
|
||||||
|
flow-static-land@0.2.7:
|
||||||
|
version "0.2.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/flow-static-land/-/flow-static-land-0.2.7.tgz#937f9dcb2780889a609155e5d1a55a993bc2ffb3"
|
||||||
|
|
||||||
|
flow-static-land@0.2.8:
|
||||||
|
version "0.2.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/flow-static-land/-/flow-static-land-0.2.8.tgz#49617e531396928bae6eb5d8ba32e7071637e5b9"
|
||||||
|
|
||||||
for-in@^1.0.1:
|
for-in@^1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||||
|
@ -2036,6 +2114,12 @@ graphql-tag@^2.4.2, graphql-tag@^2.8.0:
|
||||||
version "2.8.0"
|
version "2.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.8.0.tgz#52cdea07a842154ec11a2e840c11b977f9b835ce"
|
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.8.0.tgz#52cdea07a842154ec11a2e840c11b977f9b835ce"
|
||||||
|
|
||||||
|
graphql@0.11.7:
|
||||||
|
version "0.11.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.11.7.tgz#e5abaa9cb7b7cccb84e9f0836bf4370d268750c6"
|
||||||
|
dependencies:
|
||||||
|
iterall "1.1.3"
|
||||||
|
|
||||||
graphql@^0.13.2:
|
graphql@^0.13.2:
|
||||||
version "0.13.2"
|
version "0.13.2"
|
||||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270"
|
resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270"
|
||||||
|
@ -2422,6 +2506,10 @@ isstream@~0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||||
|
|
||||||
|
iterall@1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.3.tgz#1cbbff96204056dde6656e2ed2e2226d0e6d72c9"
|
||||||
|
|
||||||
iterall@^1.2.1:
|
iterall@^1.2.1:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7"
|
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7"
|
||||||
|
@ -2972,6 +3060,10 @@ performance-now@^0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
|
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
|
||||||
|
|
||||||
|
phoenix@1.3.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/phoenix/-/phoenix-1.3.0.tgz#1df2c27f986ee295e37c9983ec28ebac1d7f4a3e"
|
||||||
|
|
||||||
"phoenix@file:../deps/phoenix":
|
"phoenix@file:../deps/phoenix":
|
||||||
version "1.3.2"
|
version "1.3.2"
|
||||||
|
|
||||||
|
@ -3226,6 +3318,10 @@ regenerate@^1.2.1:
|
||||||
version "1.3.3"
|
version "1.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f"
|
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f"
|
||||||
|
|
||||||
|
regenerator-runtime@^0.10.5:
|
||||||
|
version "0.10.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
|
||||||
|
|
||||||
regenerator-runtime@^0.11.0:
|
regenerator-runtime@^0.11.0:
|
||||||
version "0.11.1"
|
version "0.11.1"
|
||||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
||||||
|
@ -3905,6 +4001,14 @@ zen-observable-ts@^0.8.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
zen-observable "^0.7.0"
|
zen-observable "^0.7.0"
|
||||||
|
|
||||||
|
zen-observable@0.6.0:
|
||||||
|
version "0.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.6.0.tgz#8a6157ed15348d185d948cfc4a59d90a2c0f70ee"
|
||||||
|
|
||||||
|
zen-observable@^0.6.0:
|
||||||
|
version "0.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.6.1.tgz#01dbed3bc8d02cbe9ee1112c83e04c807f647244"
|
||||||
|
|
||||||
zen-observable@^0.7.0:
|
zen-observable@^0.7.0:
|
||||||
version "0.7.1"
|
version "0.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.7.1.tgz#f84075c0ee085594d3566e1d6454207f126411b3"
|
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.7.1.tgz#f84075c0ee085594d3566e1d6454207f126411b3"
|
||||||
|
|
|
@ -14,6 +14,7 @@ defmodule Faces.Application do
|
||||||
supervisor(FacesWeb.Endpoint, []),
|
supervisor(FacesWeb.Endpoint, []),
|
||||||
# Start your own worker by calling: Faces.Worker.start_link(arg1, arg2, arg3)
|
# Start your own worker by calling: Faces.Worker.start_link(arg1, arg2, arg3)
|
||||||
# worker(Faces.Worker, [arg1, arg2, arg3]),
|
# worker(Faces.Worker, [arg1, arg2, arg3]),
|
||||||
|
supervisor(Absinthe.Subscription, [FacesWeb.Endpoint])
|
||||||
]
|
]
|
||||||
|
|
||||||
# See https://hexdocs.pm/elixir/Supervisor.html
|
# See https://hexdocs.pm/elixir/Supervisor.html
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
defmodule FacesWeb.UserSocket do
|
defmodule FacesWeb.UserSocket do
|
||||||
use Phoenix.Socket
|
use Phoenix.Socket
|
||||||
|
use Absinthe.Phoenix.Socket, schema: FacesWeb.Schema
|
||||||
|
|
||||||
## Channels
|
## Channels
|
||||||
# channel "room:*", FacesWeb.RoomChannel
|
# channel "room:*", FacesWeb.RoomChannel
|
||||||
|
|
||||||
## Transports
|
## Transports
|
||||||
transport :websocket, Phoenix.Transports.WebSocket
|
transport(:websocket, Phoenix.Transports.WebSocket)
|
||||||
# transport :longpoll, Phoenix.Transports.LongPoll
|
# transport :longpoll, Phoenix.Transports.LongPoll
|
||||||
|
|
||||||
# Socket params are passed from the client and can
|
# Socket params are passed from the client and can
|
||||||
|
|
|
@ -1,43 +1,52 @@
|
||||||
defmodule FacesWeb.Endpoint do
|
defmodule FacesWeb.Endpoint do
|
||||||
use Phoenix.Endpoint, otp_app: :faces
|
use Phoenix.Endpoint, otp_app: :faces
|
||||||
|
use Absinthe.Phoenix.Endpoint
|
||||||
|
|
||||||
socket "/socket", FacesWeb.UserSocket
|
socket("/socket", FacesWeb.UserSocket)
|
||||||
|
|
||||||
# Serve at "/" the static files from "priv/static" directory.
|
# Serve at "/" the static files from "priv/static" directory.
|
||||||
#
|
#
|
||||||
# You should set gzip to true if you are running phoenix.digest
|
# You should set gzip to true if you are running phoenix.digest
|
||||||
# when deploying your static files in production.
|
# when deploying your static files in production.
|
||||||
plug Plug.Static,
|
plug(
|
||||||
at: "/", from: :faces, gzip: false,
|
Plug.Static,
|
||||||
|
at: "/",
|
||||||
|
from: :faces,
|
||||||
|
gzip: false,
|
||||||
only: ~w(css fonts images js favicon.ico robots.txt)
|
only: ~w(css fonts images js favicon.ico robots.txt)
|
||||||
|
)
|
||||||
|
|
||||||
# Code reloading can be explicitly enabled under the
|
# Code reloading can be explicitly enabled under the
|
||||||
# :code_reloader configuration of your endpoint.
|
# :code_reloader configuration of your endpoint.
|
||||||
if code_reloading? do
|
if code_reloading? do
|
||||||
socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
|
socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket)
|
||||||
plug Phoenix.LiveReloader
|
plug(Phoenix.LiveReloader)
|
||||||
plug Phoenix.CodeReloader
|
plug(Phoenix.CodeReloader)
|
||||||
end
|
end
|
||||||
|
|
||||||
plug Plug.Logger
|
plug(Plug.Logger)
|
||||||
|
|
||||||
plug Plug.Parsers,
|
plug(
|
||||||
|
Plug.Parsers,
|
||||||
parsers: [:urlencoded, :multipart, :json],
|
parsers: [:urlencoded, :multipart, :json],
|
||||||
pass: ["*/*"],
|
pass: ["*/*"],
|
||||||
json_decoder: Poison
|
json_decoder: Poison
|
||||||
|
)
|
||||||
|
|
||||||
plug Plug.MethodOverride
|
plug(Plug.MethodOverride)
|
||||||
plug Plug.Head
|
plug(Plug.Head)
|
||||||
|
|
||||||
# The session will be stored in the cookie and signed,
|
# The session will be stored in the cookie and signed,
|
||||||
# this means its contents can be read but not tampered with.
|
# this means its contents can be read but not tampered with.
|
||||||
# Set :encryption_salt if you would also like to encrypt it.
|
# Set :encryption_salt if you would also like to encrypt it.
|
||||||
plug Plug.Session,
|
plug(
|
||||||
|
Plug.Session,
|
||||||
store: :cookie,
|
store: :cookie,
|
||||||
key: "_faces_key",
|
key: "_faces_key",
|
||||||
signing_salt: "SBTuT23J"
|
signing_salt: "SBTuT23J"
|
||||||
|
)
|
||||||
|
|
||||||
plug FacesWeb.Router
|
plug(FacesWeb.Router)
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Callback invoked for dynamically configuring the endpoint.
|
Callback invoked for dynamically configuring the endpoint.
|
||||||
|
|
|
@ -19,4 +19,15 @@ defmodule FacesWeb.Schema do
|
||||||
resolve(&Resolvers.People.create_person/3)
|
resolve(&Resolvers.People.create_person/3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subscription do
|
||||||
|
@desc "New person added"
|
||||||
|
field :person_added, :person do
|
||||||
|
config(fn _, _ ->
|
||||||
|
{:ok, "person_added"}
|
||||||
|
end)
|
||||||
|
|
||||||
|
trigger(:import_person, topic: fn _ -> "person_added" end)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
5
mix.exs
5
mix.exs
|
@ -37,13 +37,14 @@ defmodule Faces.Mixfile do
|
||||||
{:phoenix_pubsub, "~> 1.0"},
|
{:phoenix_pubsub, "~> 1.0"},
|
||||||
{:phoenix_ecto, "~> 3.2"},
|
{:phoenix_ecto, "~> 3.2"},
|
||||||
{:postgrex, ">= 0.0.0"},
|
{:postgrex, ">= 0.0.0"},
|
||||||
{:phoenix_html, "~> 2.10"},
|
{:phoenix_html, "~> 2.10", override: true},
|
||||||
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
||||||
{:gettext, "~> 0.11"},
|
{:gettext, "~> 0.11"},
|
||||||
{:cowboy, "~> 1.0"},
|
{:cowboy, "~> 1.0"},
|
||||||
{:tentacat, "~> 0.9.0"},
|
{:tentacat, "~> 0.9.0"},
|
||||||
{:absinthe_plug, "~> 1.4"},
|
{:absinthe_plug, "~> 1.4"},
|
||||||
{:poison, "~> 2.1.0", override: true}
|
{:poison, "~> 2.1.0", override: true},
|
||||||
|
{:absinthe_phoenix, "~> 1.4.0"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
1
mix.lock
1
mix.lock
|
@ -1,5 +1,6 @@
|
||||||
%{
|
%{
|
||||||
"absinthe": {:hex, :absinthe, "1.4.10", "9f8d0c34dfcfd0030d3a3f123c7501e99ab59651731387289dad5885047ebb2a", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
"absinthe": {:hex, :absinthe, "1.4.10", "9f8d0c34dfcfd0030d3a3f123c7501e99ab59651731387289dad5885047ebb2a", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
|
"absinthe_phoenix": {:hex, :absinthe_phoenix, "1.4.2", "cb84c81b94103fdfbbdd8b83b7b4b70a850ab7d3be6a1e56b96de2bb854b09b6", [:mix], [{:absinthe, "~> 1.4.0", [hex: :absinthe, repo: "hexpm", optional: false]}, {:absinthe_plug, "~> 1.4.0", [hex: :absinthe_plug, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.2", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.10.5", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:poison, "~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"absinthe_plug": {:hex, :absinthe_plug, "1.4.2", "01bf16f0a637869bcc0a1919935f08ff853501004e7549ddaa3a7788deb48965", [:mix], [{:absinthe, "~> 1.4", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
"absinthe_plug": {:hex, :absinthe_plug, "1.4.2", "01bf16f0a637869bcc0a1919935f08ff853501004e7549ddaa3a7788deb48965", [:mix], [{:absinthe, "~> 1.4", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
"certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
||||||
|
|
Reference in a new issue