我已经在elixir中创建了一个凤凰应用程序。我使用了生成工具来创建所有CRUD功能和CRUD页面。
当前使用:
def index(conn, _params) do
data = Repo.all(Object)
render(conn, "index.html", data: data)
end
如何用GraphQl实现替换它,因为我目前有能力通过指定的URL传递GraphQl查询。从表中获取所有记录。该文档谈论了使用Absinthe_phoenix插头并将其添加到管道中。最终,这只是替换我拥有并要求URL的当前网页,所有当前页面都是Phoenix运行脚手架命令以生成CRUD和数据库架构时创建的页面。
。 。我需要保留所有这些CRUD页面,但让它们运行grapql查询。因此,在显示数据库中所有记录的页面上,我需要它而不是运行
data = Repo.all(Object)
它应该运行
{
objects{
field1,
field2
}
}
获取所有数据。如何在控制器中运行GraphQl查询?
这是我需要在GraphQL架构中运行的查询
query do
@doc """
Returns all the records from a database
"""
field :objects, list_of(:object) do
resolve &Billingplus.ObjectResolver.all/2
end
end
您需要在GQL架构中创建引用,并具有针对不同事物的解析器函数。您不会将其放在控制器中。我将向您展示一个从DB到Absinthe实施的"事物"的前后示例。
休息和GQL是不同的范式/接口。
您的项目中有没有工作的GQL?展示您所做的事情,以便我们提供建议。
示例突变:
mutation do
@desc "Create an OAuth2 client"
field :create_oauth2_client, :oauth2_client do
arg(:app_id, non_null(:uuid4))
arg(:client_id, non_null(:string))
arg(:client_secret, non_null(:string))
arg(:oauth2_provider_id, non_null(:uuid4))
resolve(&Resolvers.OAuth2Client.create_oauth2_client/3)
end
end
示例查询:
query do
@desc "Get an OAuth2 client"
field :oauth2_client, :oauth2_client do
arg(:id, non_null(:uuid4))
resolve(&Resolvers.OAuth2Client.get_oauth2_client/3)
end
end
示例模式对象:
defmodule ApiWeb.Schema.OAuth2Client do
use Absinthe.Schema.Notation
alias Api.Auth.Apps
alias Api.Auth.OAuth2Providers
alias Api.Util
@desc "An OAuth2 client"
object :oauth2_client do
field(:id, :uuid4)
field(:client_id, :string)
field(:client_secret, :string)
field(:app, :app,
resolve: fn oauth2_client, _, _ ->
Apps.get_app(oauth2_client.app_id)
|> Util.handle_not_found_error_and_wrap("App not found.")
end
)
field(:oauth2_provider, :oauth2_provider,
resolve: fn oauth2_client, _, _ ->
OAuth2Providers.get_oauth2_provider(oauth2_client.oauth2_provider_id)
|> Util.handle_not_found_error_and_wrap("OAuth2Provider not found.")
end
)
end
end
示例解析器:
defmodule ApiWeb.Resolvers.OAuth2Client do
alias Api.Auth.OAuth2Clients
#
# QUERIES
#
def get_oauth2_client(_parent, %{id: id}, _resolution) do
OAuth2Clients.get_oauth2_client(id)
end
def get_oauth2_clients_by_app(_parent, %{app_id: app_id}, _resolution) do
OAuth2Clients.get_oauth2_clients_by_app(app_id)
end
#
# MUTATIONS
#
def create_oauth2_client(_parent, params, _resolution) do
OAuth2Clients.create_oauth2_client(%{
app_id: params.app_id,
oauth2_provider_id: params.oauth2_provider_id,
client_id: params.client_id,
client_secret: params.client_secret
})
end
end
示例上下文:
defmodule Api.Auth.OAuth2Clients do
@moduledoc """
The OAuth2Clients context.
"""
import Ecto.Query, warn: false
alias Api.Repo
alias Api.Auth.OAuth2Clients.OAuth2Client
alias Api.Util
@doc """
Returns the list of OAuth2Clients.
## Examples
iex> list_oauth2_clients()
{:ok, [%OAuth2Client{}, ...]}
"""
def list_oauth2_clients do
Repo.all(OAuth2Client)
|> Util.handle_not_found_error_and_wrap("No OAuth2Clients found.")
end
@doc """
Gets a single OAuth2Client.
Returns `{:error, %NotFoundError{}}` if the OAuth2Client does not exist.
## Examples
iex> get_oauth2_client(123)
{:ok, %OAuth2Client{}}
iex> get_oauth2_client(456)
{:error, %NotFoundError{}}
"""
def get_oauth2_client(id) do
Repo.get(OAuth2Client, id)
|> Util.handle_not_found_error_and_wrap("OAuth2Client not found.")
end
@doc """
Gets a single OAuth2Client by `client_id` and `provider_id`.
Returns `{:error, %NotFoundError{}}` if the OAuth2Client does not exist.
## Examples
iex> get_oauth2_client_by_client_and_provider_id(123)
{:ok, %OAuth2Client{}}
iex> get_oauth2_client_by_client_and_provider_id(456)
{:error, %NotFoundError{}}
"""
def get_oauth2_client_by_client_and_provider_id(client_id, provider_id) do
from(o in OAuth2Client,
where: o.client_id == ^client_id and o.oauth2_provider_id == ^provider_id
)
|> Repo.one()
|> Util.handle_not_found_error_and_wrap("OAuth2Client not found.")
end
@doc """
Gets a list of OAuth2Client by App.
Returns `{:error, %NotFoundError{}}` if there are no OAuth2Client to return.
## Examples
iex> get_oauth2_clients_by_app(123)
{:ok, [%OAuth2Client{}, ...]}
iex> get_oauth2_clients_by_app(456)
{:error, %NotFoundError{}}
"""
def get_oauth2_clients_by_app(app_id) do
from(o in OAuth2Client,
where: o.app_id == ^app_id
)
|> Repo.all()
|> Util.handle_not_found_error_and_wrap("App not found.")
end
@doc """
Gets an OAuth2Client by `App` and `Provider`
Returns `{:error, %NotFoundError{}}` if there is no `OAuth2Client` to return.
## Examples
iex> get_oauth2_clients_by_app_and_provider(123)
{:ok, [%OAuth2Client{}, ...]}
iex> get_oauth2_clients_by_app_and_provider(456)
{:error, %NotFoundError{}}
"""
def get_oauth2_client_by_app_and_provider(app_id, provider_id) do
from(o in OAuth2Client,
where: o.app_id == ^app_id and o.oauth2_provider_id == ^provider_id
)
|> Repo.one()
|> Util.handle_not_found_error_and_wrap("App not found.")
end
@doc """
Creates an OAuth2Client.
## Examples
iex> create_oauth2_client(%{field: value})
{:ok, %OAuth2Client{}}
iex> create_oauth2_client(%{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def create_oauth2_client(attrs) do
%OAuth2Client{}
|> OAuth2Client.create(attrs)
|> Repo.insert()
end
@doc """
Updates an OAuth2Client.
## Examples
iex> update_oauth2_client(oauth2_client, %{field: new_value})
{:ok, %OAuth2Client{}}
iex> update_oauth2_client(oauth2_client, %{field: bad_value})
{:error, %Ecto.Changeset{}}
"""
def update_oauth2_client(%OAuth2Client{} = oauth2_client, attrs) do
oauth2_client
|> OAuth2Client.update(attrs)
|> Repo.update()
end
@doc """
Deletes a OAuth2Client.
## Examples
iex> delete_oauth2_client(oauth2_client)
{:ok, %OAuth2Client{}}
iex> delete_oauth2_client(oauth2_client)
{:error, %Ecto.Changeset{}}
"""
def delete_oauth2_client(%OAuth2Client{} = oauth2_client) do
Repo.delete(oauth2_client)
end
end
示例模型/模型:
defmodule Api.Auth.OAuth2Clients.OAuth2Client do
use Ecto.Schema
import Ecto.Changeset
alias Api.Auth.Apps.App
alias Api.Auth.OAuth2Providers.OAuth2Provider
@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "oauth2_clients" do
field(:client_id, :string)
field(:client_secret, :string)
belongs_to(:app, App)
belongs_to(:oauth2_provider, OAuth2Provider)
timestamps()
end
def create(app, attrs) do
app
|> cast(attrs, [:client_id, :client_secret, :oauth2_provider_id, :app_id])
|> validate_required([:client_id, :client_secret, :oauth2_provider_id, :app_id])
|> foreign_key_constraint(:app_id)
|> foreign_key_constraint(:oauth2_provider_id)
end
def update(app, attrs) do
app
|> cast(attrs, [:client_id, :client_secret, :oauth2_provider_id, :app_id])
|> foreign_key_constraint(:app_id)
|> foreign_key_constraint(:oauth2_provider_id)
end
end
示例迁移:
defmodule Api.Repo.Migrations.CreateOAuth2Clients do
use Ecto.Migration
def change do
create table(:oauth2_clients, primary_key: false) do
add(:id, :binary_id, primary_key: true)
add(:client_id, :string, null: false)
add(:client_secret, :string, null: false)
add(:oauth2_provider_id, references(:oauth2_providers, type: :binary_id), null: false)
add(:app_id, references(:apps, type: :binary_id), null: false)
timestamps()
end
end
def up do
create(
constraint(:owners, :user_or_organization,
check:
"((organization_id is not null and user_id is null) or (organization_id is null and user_id is not null))"
)
)
end
def down do
drop(constraint(:owners, :user_or_organization))
end
end
这是您感到困惑的地方。您没有在路由器中引用控制器,而是指定GQL端点并在此处查询后端。
defmodule ApiWeb.Router do
use ApiWeb, :router
alias ApiWeb.OAuthController
pipeline :api do
plug(Plug.Parsers,
parsers: [:json, Absinthe.Plug.Parser],
pass: ["*/*"],
json_decoder: Jason
)
plug(:accepts, ["json"])
end
scope "/" do
pipe_through(:api)
get("/oauth2", OAuthController, :callback)
post("/graphql", Absinthe.Plug, schema: ApiWeb.Schema)
forward("/graphiql", Absinthe.Plug.GraphiQL,
schema: ApiWeb.Schema,
json_codec: Jason
)
end
end
在凤凰项目中实现苦艾酒有很多不同的组成部分。我花了一段时间将我的头缠绕在上面 - 主要是因为对象定义有点奇怪,您可以制作伪虚拟字段。首先,在查询内解决结构参考的能力也有些混乱。