absinthe-graphql / absinthe_plug Goto Github PK
View Code? Open in Web Editor NEWPlug support for Absinthe, the GraphQL toolkit for Elixir
Home Page: https://hex.pm/packages/absinthe_plug
License: MIT License
Plug support for Absinthe, the GraphQL toolkit for Elixir
Home Page: https://hex.pm/packages/absinthe_plug
License: MIT License
I notice that all the assets are being pull up from the CDN. Is there any way to add that locally so it can work on offline connections?
There is only one reason I am asking and it's that some countries (Cuba in this case) can't access to the internet 24/7 so use GraphiQL is kind of impossible if it loads from the CDN. Also, working from a place that I can't access to the internet (like airplanes)
Do you have any suggestion in how to fix this? I am thinking that the only way is to download GraphiQL tool and run it locally and do not use this one I guess, but I am wondering if there if we could add offline support.
Hello.
How should I setup my route in a router.ex
to accept OPTIONS
requests from a client?
Thanks!
select_mode
is expecting a document: nil
when it's given a list containing queries.
I patched it on my side with:
defp select_mode(%{queries: [%Absinthe.Plug.Request.Query{document: nil}]}), do: :start_interface
I can create a PR if you like.
what is the best way to capture the exception for the stack trace error with Absinthe.Plug
?
to Plug application I can use this: https://hexdocs.pm/rollbax/using-rollbax-in-plug-based-applications.html#content
put it but this does not capture the information of the absinthe context.
raw send to rollbar: https://gist.github.com/gullitmiranda/822c843393ede374333bd737fff34a51
this raw makes it clear that the exception is not passed to the Plug.ErrorHandler
As does express-graphql. Here's the source: https://github.com/graphql/express-graphql/blob/master/src/renderGraphiQL.js
In previous versions of absinthe_plug, we had a sweet prettify button:
But as of 3cc4889 we do not :(
I always found that to be super helpful, and would like to add it back in. It worked well where it was before, right next to the Run button above the query input.
The loss may be related to v0.9.3 of GraphiQL they removed the hardcoded prettify button. Perhaps the graphiql-workspace project didn't get the memo.
When receiving a GraphQL query document (Content-Type: application/graphql
) if the the encoding is also passed (or any other parameters for that matter), the plug will assume it's not a GraphQL document.
e.g. Content-Type: application/graphql; charset=UTF-8
will not work.
The issue is because of this line https://github.com/absinthe-graphql/absinthe_plug/blob/master/lib/absinthe/plug.ex#L169 the match here is matching exactly the string "application/graphql"
. So any other combination of parameters or encodings will obviously not match and fall through to the empty body case ({conn, ""}
).
A simple fix is to just match [<<"application/graphql", _ :: binary>>]
instead (though this is most likely wrong as any result as long as it contains that prefix will pass). However I'm unsure what the appropriate fix should be. I assume the GraphQL spec states the encoding should implicitly be UTF-8 (like JSON). So maybe the correct scenario should be a Content-Type
whose parameters are either application/graphql
only, or application/graphql
with an explicit encoding set to UTF-8. While any other parameters/combination of (or other encodings) would be a failure.
I'm happy to submit a fix, just wondering what the ideal solution should cover.
Query with unused variable:
query($userId: String!, $test: String!) {
user(id: $userId) {
id
}
}
throws:
Server: localhost:4000 (http)
Request: POST /graphql
** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Absinthe.Phase.Document.Result.format_location/1
(absinthe) lib/absinthe/phase/document/result.ex:116: Absinthe.Phase.Document.Result.format_location(nil)
(elixir) lib/enum.ex:1184: Enum."-map/2-lists^map/1-0-"/2
(elixir) lib/enum.ex:1184: Enum."-map/2-lists^map/1-0-"/2
(absinthe) lib/absinthe/phase/document/result.ex:111: Absinthe.Phase.Document.Result.format_error/1
(elixir) lib/enum.ex:1184: Enum."-map/2-lists^map/1-0-"/2
(elixir) lib/enum.ex:1184: Enum."-map/2-lists^map/1-0-"/2
(absinthe) lib/absinthe/phase/document/result.ex:42: Absinthe.Phase.Document.Result.format_result/1
(absinthe) lib/absinthe/phase/document/result.ex:12: Absinthe.Phase.Document.Result.run/2```
Right now it appears that we're not supporting passing in a root_value option, which could be used to mock out data for rapid prototyping.
Loving absinthe so far!
Just ran in an edge case (I think) when converting my app to support batching. I use a multipart form for submitting the queries and variables when one of the queries contains a file upload. That worked great when I didn't have a batching network interface, but now with batching applied I get the following error: 'no query document found'. I guess it is because normally absinthe expects the body of the document to be an array. However with multipart forms & batching the operations are part of the "operations" field.
Hi! I'm trying to find a way of modifying http response returned by Absinthe Plug depending on results of a query (mutation) execution. For example, I want to put a new cookie into the response if mutation resolver has successfully returned some value (User model). I'm trying to build such workflow:
In such case I don't mix transport level with the logic and all transport-related stuff encapsulated in a Pipeline Phase.
Is this workflow even possible? Now I have several issues:
Maybe there is another way of doing this and I'm doing something wrong. Please help.
In Absinthe v1.2, we have a processing pipeline that can be customized. The pipeline built by the plug (see setup_pipeline
) needs to be exposed for modification by users.
Hi guys, first of all, thank you for the great library!
I am not sure if it is an issue rather than a question but I would like to be able to upload files and use batching at the same time.
I was playing around with CURL to build the working request first and then to implement a plugin for the apollo-client library to make things work.
For the single request everything works great
curl -X POST \
-F query="mutation createPost(\$text: String, \$image: String){createPost(image: \$image, text:\$text, locked: false) { id }}" \
-F operationName="createPost" \
-F variables="{\"text\":\"hello\",\"image\":\"me_jpg\"}" \
-F [email protected] \
localhost:4000/graphql
The question is, how can I convert this single request in a batched one?
Thank you in advance!
I'm not sure whether this is an issue with Apollo or Absinthe, but figured I would start here in case batched responses don't match the Apollo expectations.
I have a very basic query:
{ users { id name } }
and am using {:absinthe_plug, git: "https://github.com/absinthe-graphql/absinthe_plug.git"},
in my mix.deps
file.
This query works fine when I have batching switched off in Apollo, but I get an error with I switch it on (note I'm not even trying to send multiple queries at once, just one query):
Network error: Error writing result to store for query { users { id name } } /nCannot read property 'users' of undefined
The response from Absinthe is:
[{"operationName":null,"payload":{"data":{"users":[]}}}]
Show basic, full example of how to use another plug to populate the execution context (for, eg, authorization).
I'm a little confused on how the GraphiQL feature is intended.
I assumed it's just to serve a separate JS app for GraphiQL. Thus, we had this configuration in our router:
# The API endpoint
scope "/api/v1" do
pipe_through :api
forward "/graphql", Absinthe.Plug, schema: Myapp.Schema
end
# The GraphiQL app
if Mix.env == :dev do
forward "/graphiql", Absinthe.Plug.GraphiQL, schema: Myapp.Schema
end
The problem we have with this setup is that /graphiql
also serves the GraphQL API. Two other people tried using the GraphiQL app, entering its own URL - /graphiql
- instead of the API URL - /api/v1/graphql
. Surprisingly for me, it worked. Except since the second endpoint is not piped through API, the GraphQL resolvers didn't get receive proper context and the API failed in various subtle and not so subtle ways. This was fixed by explaining the guys they should use the correct API endpoint.
Please explain, are we doing something idiomatically wrong?
... please :)
Relatively new to the library, and trying to create my first compiled doc provider.
What happened:
use Absinthe.Plug.DocumentProvider.Compiled
Attempted function clauses (showing 1 out of 1):
defp do_process(%{params: %{"id" => document_key}} = request)
do_process
Conclusion
The second definition is expecting two args, but it will only every have 1. Currently looks like do_process(request, _)
and it should look like do_process(request)
.
That could be intentional, sorry if it is! Just a little confused about it.
Right now we have:
[description: "A plug for Absinthe, an experimental GraphQL toolkit",
files: ["lib", "mix.exs", "README*"],
maintainers: ["Ben Wilson", "Bruce Williams"],
licenses: ["BSD"],
links: %{github: "https://github.com/CargoSense/absinthe_plug"}]
I believe the description could get rid of the 'experimental' word and the links need to be updated.
Hey guys!
Does the library support multiple file uploading? If so could you please provide with an example of schema and especially an example of a request. Thanks.
@tlvenn Do we need to update the "advanced" GraphiQL (now GraphiQL Workspace), based on your conversation here: OlegIlyenko/graphql-toolbox#3 ?
This may very well be user error :)
I'm trying to set up a 1.3 project with absinthe. However, as soon as I add the plug, my default Page controller test stops passing.
1) test GET / (MyApp.Web.PageControllerTest)
test/my_app/web/controllers/page_controller_test.exs:4
** (Plug.Conn.AlreadySentError) the response was already sent
stacktrace:
(plug) lib/plug/conn.ex:950: Plug.Conn.register_before_send/2
(my_app) lib/my_app/web/router.ex:4: MyApp.Web.Router.browser/2
(my_app) lib/my_app/web/router.ex:1: anonymous fn/1 in MyApp.Web.Router.__match_route__/4
(phoenix) lib/phoenix/router.ex:273: Phoenix.Router.__call__/1
(my_app) lib/my_app/web/endpoint.ex:1: MyApp.Web.Endpoint.plug_builder_call/2
(my_app) lib/my_app/web/endpoint.ex:1: MyApp.Web.Endpoint.call/2
(phoenix) lib/phoenix/test/conn_test.ex:224: Phoenix.ConnTest.dispatch/5
test/my_app/web/controllers/page_controller_test.exs:5: (test)
It seems like as soon I add the plug to the endpoint, the "/" url starts returning early.
Possibly I've missed a step, but I'm not sure where to start looking. Any help would be appreciated
1.) phx.new my_app
2.) add schema file in lib/my_app/web/schema.ex
defmodule MyApp.Web.Schema do
use Absinthe.Schema
@fake_db %{
"foo" => %{id: "foo", name: "Foo", value: 4},
"bar" => %{id: "bar", name: "Bar", value: 5}
}
@desc "A valuable Item"
object :item do
field :id, :id
@desc "The item's name"
field :name, :string
field :value, :integer, description: "Recently appraised value"
end
query do
@desc "Get an item by ID"
field :item, :item do
@desc "The ID of the item"
arg :id, type: :id
resolve fn %{id: id}, _ ->
{:ok, Map.get(@fake_db, id)}
end
end
end
end
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json, Absinthe.Plug.Parser],
json_decoder: Poison
plug Absinthe.Plug,
schema: MyApp.Schema
this is the point the tests fail
defmodule MyApp.Web.Router do
use MyApp.Web, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", MyApp.Web do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
end
forward "/api", Absinthe.Plug, schema: MyApp.Web.Schema
# Other scopes may use custom stacks.
# scope "/api", MyApp.Web do
# pipe_through :api
# end
end
I tried putting the plug line in a few locations but it made no difference.
Using
absinthe 1.2.5
absinthe_plug 1.2.2
When I run the following introspection query
query IntrospectionQuery {
__schema {
queryType { name }
mutationType { name }
subscriptionType { name }
types {
...FullType
}
directives {
name
description
locations
args {
...InputValue
}
}
}
}
fragment FullType on __Type {
kind
name
description
fields(includeDeprecated: true) {
name
description
args {
...InputValue
}
type {
...TypeRef
}
isDeprecated
deprecationReason
}
inputFields {
...InputValue
}
interfaces {
...TypeRef
}
enumValues(includeDeprecated: true) {
name
description
isDeprecated
deprecationReason
}
possibleTypes {
...TypeRef
}
}
fragment InputValue on __InputValue {
name
description
type { ...TypeRef }
defaultValue
}
fragment TypeRef on __Type {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}
}
}
}
}
I get the following error
** (KeyError) key :no_query_message not found in: %{adapter: nil, context: %{}, interface: :advanced, json_codec: %{module: Poison, opts: []}, pipeline: {Absinthe.Plug, :default_pipeline}, schema_mod: Core.GraphQL.Schema}
lib/absinthe/plug.ex:146: Absinthe.Plug.execute/2
lib/absinthe/plug.ex:115: Absinthe.Plug.call/2
(phoenix) lib/phoenix/router/route.ex:154: Phoenix.Router.Route.forward/4
(webapp) lib/phoenix/router.ex:261: Webapp.Router.dispatch/2
(webapp) web/router.ex:1: Webapp.Router.do_call/2
(webapp) lib/webapp/endpoint.ex:1: Webapp.Endpoint.phoenix_pipeline/1
(webapp) lib/plug/debugger.ex:123: Webapp.Endpoint."call (overridable 3)"/2
(webapp) lib/webapp/endpoint.ex:1: Webapp.Endpoint.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
At this moment I couldn't run other query because I'm using the require('graphql/utilities').introspectionQuery
from Javascript to start my babelRelayPlugin. I'll see if I can generate the schema with mix absinthe.schema.json
so I can try other queries.
Debug logging on logs the query at the moment, it should also log variables.
After upgrading to v1.4, it seems that GraphiQL does not like interface types anymore. The type is missing from the schema docs and the IDE claims the type doesn't exist, but the query will successfully execute.
ticket schema:
object :ticket do
field :id, :integer
field :test_iface, :iface_test do
resolve fn _, _ ->
{:ok, %{type: "one", name: "foo", email: "bar", custom: "custom"}}
end
end
end
iface_test schema:
object :one do
field :name, :string
field :email, :string
field :custom, :string
interface :iface_test
end
object :two do
field :name, :string
field :email, :string
field :unique, :string
interface :iface_test
end
interface :iface_test do
field :name, :string
field :email, :string
resolve_type fn
%{type: "one"}, _ -> :one
%{type: "two"}, _ -> :two
_, _ -> :one
end
end
I don't think I'm missing anything, and this same schema worked on v1.3. Let me know if you need anything else!
The graphiql-workspace.min.js at https://unpkg.com/[email protected]/graphiql-workspace.min.js is truncated so graphiql won't load.
Changing this line: https://github.com/absinthe-graphql/absinthe_plug/blob/master/lib/absinthe/plug/graphiql.ex#L65 to 1.0.3 seems to fix it.
Hi!
I'm experiencing issues while using Absinthe.Plug
in conjunction with Sentry (an error logging service). I can't get Sentry to report an error (neither through a Plug nor through :error_logger
).
I've managed to find a similar issue on their issue tracker and after some digging figured out that this line causes the same problem as the one outlined in the issue.
My question is, is there a way to implement custom error handling with this library? Or o way to get the described integration to work?
Using graphiql workspace with the socket_url
option will prevent graphiql workspace from rendering in the browser because of a js syntax error.
I like to keep access tokens in Secure, HttpOnly cookies (as opposed to localStorage) to ensure tokens are not vulnerable to XSS attacks. I combine that with the X-CSRF-Token
header to mitigate CSRF attacks.
It would be great to have a way to inject <%= csrf_meta_tag() %>
and have the X-CSRF-Token
header set by default.
Absinthe.Language.Document.get_operation/2
to get the right Absinthe.Language.OperationDefinition.t
.operation
(ie, non-:query
requires POST
)Absinthe.run/3
(as the :operation_name
option)Here is where I specified my default_url:
forward "/graphiql",
Absinthe.Plug.GraphiQL,
schema: Eggl.Schema,
default_headers: {__MODULE__, :graphiql_headers},
default_url: "/graphql"
But when I visit /graphiql
, the URL is always http://localhost:4000/graphiql
(notice the i
). I would have expected it to be http://localhost:4000/graphql
.
This persists across different browsers and even different machines so its not a local storage cache issue.
See also: absinthe-graphql/absinthe#354 (comment)
I've got graphiql mounted in dev and I'm able to make mutations as per my schema. But, the "docs" tab only shows "NO SCHEMA AVAILABLE".
I'm wondering if this is supposed to work (indicating I probably have it misconfigured), or if this is not a feature of absinthe_plug.
Thanks!
if Mix.env == :dev do
forward "/graphiql",
Absinthe.Plug.GraphiQL,
schema: DeviceService.Api.Factory.Schema,
interface: :simple
end
Absinthe dependency seems like it should be relaxed to use ~> 1.3.0-beta.0
to allow any beta release to work with absinth_plug
.
I'm happy to send a PR if it's helpful. Work is ready at:
matthewlehner/absinthe_plug@f334567
Sorry to open this here, but I'm not sure where the best place is and since this is where graphql-playground gets consumed I figured I would start here.
Can https://github.com/absinthe-graphql/graphql-playground be updated to pull in latest changes from upstream? I had some fixes in there I would love to be able to use.
Thanks!
pipeline Context plug fires
fires for graphiql
but not from client client hitting socket
defmodule HyrWeb.Router do
use Phoenix.Router
import Plug.Conn
import Phoenix.Controller
pipeline :api do
plug :accepts, ["json"]
plug HyrWeb.Context
end
scope "/" do
pipe_through :api
forward "/socket", Absinthe.Plug, # <- does NOT hit Context
schema: HyrWeb.Schema,
socket: HyrWeb.Channels.ShiftSocket
forward "/graphiql", Absinthe.Plug.GraphiQL, # <- DOES hit Context
schema: HyrWeb.Schema,
interface: :simple,
socket: HyrWeb.Channels.ShiftSocket
end
end
the pipeline is just ignored for all my client calls. I don't see the IO.inspect
that is shown below. I suspect it has something to do with Absinthe.Plug
as that's the only thing that's different between the two endpoints. Don't know how it could be preventing pipe_through
. Probably a socket issue but graphiql
with sockets is getting the context pipe fine.
Here is my Context.ex
but I am running the graphiql calls fine and can 100% confirm that Context.ex
is doing what it is supposed to there.
defmodule HyrWeb.Context do
@behaviour Plug
import Plug.Conn
def init(opts), do: opts
def call(conn, _) do
context = build_context(conn)
IO.inspect [context: context]
put_private(conn, :absinthe, %{context: context})
end
defp build_context(conn) do
with %{} = user <- Hyr.Repo.get_by(Hyr.Accounts.User, phone: "+1-212-555-5555") do
%{current_user: user}
else
_ -> %{}
end
end
end
Following the documentation and inserting the following in the router:
get "/graphiql", Absinthe.Plug.GraphiQL, schema: MyApp.Schema
When I visit the url "/graphiql" the response I receive is No query document supplied
. What I expected to see was the graphiql UI here.
After providing a query the graphiql UI renders, however the response doesn't seem quite right. It returns what appears to be the graphiql.html.eex
file.
Is it possible to return arbitrary HTTP status codes, e.g. a 401 Unauthorized when a particular field requires authentication?
I'm currently using a custom private
function to wrap resolver functions, which returns {:error, "Must be logged in"}
if the user is not authenticated:
query do
field :posts, list_of(:post) do
resolve private &App.PostResolver.all/2
end
end
defp private(fun) do
fn args, %{context: context} = info ->
case context do
%{current_user: user} when not is_nil(user) -> fun.(args, info)
_ -> {:error, "Must be logged in"}
end
end
end
This results in a 200 status code even when an error is returned, which complicates error handling. It would be nice if we could return, e.g. {:error, message: "...", plug_status: 401}
.
You can use Plug's exception protocol for this, but it feels kind of wrong:
case context do
%{current_user: user} when not is_nil(user) -> fun.(args, info)
_ -> raise App.Unauthorized
end
defmodule App.Unauthorized do
defexception [message: "Must be logged in", plug_status: 401]
end
I'd like to mount GraphiQL to /api, which will also be the GraphQL API endpoint, to make it just a bit easier to discover and experiment with the API.
Even if I mount the GraphiQL plug at /api, it still wants to post to /graphiql. I have a hacky workaround in that I mount the plain GraphQL API at /graphiql, then point everything else at /api.
Any idea why this is happening? A quick glance through the source isn't hugely revealing. I'm wondering if it is a GraphiQL default that isn't being updated via the plug? If so, seems like it would fail if mounted anywhere else.
As an aside, is there any reason why doing this would be a bad idea? I'm explicitly trying to make this API as easy to discover and use as possible, but maybe there are gotchas of which I'm not aware.
Thanks.
def deps do
[
<<<<<<< HEAD
...,
=======
{:absinthe_plug, "~> 1.2.3"},
>>>>>>> master
{:poison, "~> 1.3.0"}
]
end
In the event the query document is in a GET body this just pushes a blank document on to Absinthe, which is wrong.
Hey @tlvenn,
#130 seems to have introduced an issue with both the simple and workspace graphiql UIs. Running a subscription gets:
CC @mgtitimoli
Sensitive parameters such as password
should be filtered from the logs. This works easily with variables, I'm not so sure how it would work with logging the schema document itself.
I'm trying to upload a picture to a Phoenix application from my React Native app, using a GraphQL mutation that sends the picture as an argument. Unfortunately, Absinthe throws an error when receiving the mutation, possibly because of a malformed request.
Server: absinthe 1.4.0-rc.2
, absinthe_plug 1.4.0-rc.0
Client: react-native 0.49.3
, apollo-upload-client 5.1.1
In my schema.ex
:
field :update_profile_picture, type: :string do
arg :picture, non_null(:upload)
resolve fn args, _ ->
{:ok, "success"}
end
end
My mutation:
mutation UpdateProfilePicture($picture: Upload!) {
updateProfilePicture(picture: $picture)
}
and I run it from the client like this:
const image = … // my image object
const file = new ReactNativeFile({
uri: image.path,
type: 'image/jpeg',
name: 'test.jpg'
})
this.props.updateProfilePicture({
variables: {
picture: file,
},
})
After submitting, I see the following in my server logs:
[error] #PID<0.10558.0> running MyApp.Endpoint terminated
Server: api.myapp.local:4000 (http)
Request: POST /graphql
** (exit) an exception was raised:
** (BadMapError) expected a map, got: {"operationName", "UpdateProfilePicture"}
(elixir) lib/map.ex:424: Map.get({"operationName", "UpdateProfilePicture"}, "query", "")
lib/absinthe/plug/request/query.ex:131: Absinthe.Plug.Request.Query.extract_raw_document/2
lib/absinthe/plug/request/query.ex:51: Absinthe.Plug.Request.Query.parse/3
(elixir) lib/enum.ex:1259: anonymous fn/3 in Enum.map/2
(stdlib) lists.erl:1263: :lists.foldl/3
(elixir) lib/enum.ex:1828: Enum.map/2
lib/absinthe/plug/request.ex:54: Absinthe.Plug.Request.build_request/4
lib/absinthe/plug/request.ex:49: Absinthe.Plug.Request.parse/2
lib/absinthe/plug.ex:217: Absinthe.Plug.execute/2
lib/absinthe/plug.ex:155: Absinthe.Plug.call/2
(phoenix) lib/phoenix/router/route.ex:161: Phoenix.Router.Route.forward/4
(phoenix) lib/phoenix/router.ex:278: Phoenix.Router.__call__/1
(myapp) lib/myapp/endpoint.ex:1: MyApp.Endpoint.plug_builder_call/2
(myapp) lib/plug/debugger.ex:99: MyApp.Endpoint."call (overridable 3)"/2
(myapp) lib/myapp/endpoint.ex:1: MyApp.Endpoint.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) /Users/richeterre/Code/MyApp/myapp-phoenix/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
Is this something that could be fixed by making minor adjustments on the client side, as suggested by @confiks in #98? As I understand it, apollo-upload-client
has sparked the interest of the Apollo core team and might become more "official" in the future: apollographql/apollo#65
With the addition of #28, it's clear we need to have better documentation around the various options you can pass.
Hi!
With GraphQL being data format agnostic and all it might be nice to be able to use absinthe_plug
with a custom serializer like msgpax or maybe just :erlang.term_to_binary
plug Absinthe.Plug,
schema: MyApp.Schema,
serializer: MyApp.Serializer
where MyApp.Serializer
would implement callbacks similar to those for phoenix channels.
The graphiql-workspace javascript from the unpkg.com CDN seems to contain invalid javascript. I am geeting an syntax error.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.