OpenAPI Generator에서 Elixir 기반 Moralis API 클라이언트 만들기
이번에 시도한 코드는 kentaro/elixir-moralis 위에 놓여 있다.적당히 참고하세요.
이른바 OpenAPI
OpenAPI(정확히 말하면 The OpenAPI Specification)는 HTTP 기반의 API 규격을 기술하는 데 사용되는 규격OpenAPI Specification v3.1.0 | Introduction, Definitions, & More이다.OpenAPI에 기술된 API 규격(모드.JSON과 YAML로 작성할 수 있음)을 파트너로 하여 API 문서, 클라이언트, 서버를 자동으로 생성할 수 있는 편리한 메커니즘이다.
이 글의 관심사에 따라 OpenAPI에서 기술한 규격을 바탕으로 API 클라이언트를 자동으로 생성하는 데 사용될 것입니다.여기서 생성기로 사용해 보세요openapi-generator-cli.
npm
명령을 사용하여 설치openapi-generator-cli
.$ npm install @openapitools/openapi-generator-cli -g
Moralis API 사양
Moralis API의 규격은 Moralis Admin(사용자 등록 필요)로 통일됩니다.또한 https://deep-index.moralis.io/api-docs/v2/swagger.json 중 OpenAPI 3.0.0에 기술된 JSON 파일이 있어 Swagger Editor 읽으면 좋은 느낌을 준다.
API 클라이언트 라이브러리 만들기
프로젝트 준비
여기서 하고 싶은 일은 다음과 같다.
openapi-generator-cli
은 클라이언트를 생성하여mix 프로젝트로 실현한다.따라서 이 실장된 구성 프로그램 라이브러리를 사용하는mix 프로젝트와 동시에 존재하는 형식으로 포장을 구성해야 한다.그곳에서는 안브레라 프로젝트 같은 구조를 사용할 수 있다.mix new
시--umbrella
는 추가 옵션을 통해 안브레라 프로젝트로 프로젝트를 만들 수 있습니다.$ mix new moralis --umbrella
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating apps
* creating config
* creating config/config.exs
Your umbrella project was created successfully.
Inside your project, you will find an apps/ directory
where you can create and host many apps:
cd moralis
cd apps
mix new my_app
Commands like "mix compile" and "mix test" when executed
in the umbrella project root will automatically run
for each application in the apps/ directory.
$ mv moralis/ elixir-moralis
$ cd elixir-moralis
먼저 클라이언트 프로그램 라이브러리의 주체부터 제작한다.apps/
제작 목록.$ cd apps/
$ mix new moralis
다음으로 OpenAPI에서 기술한 모델에서 API 클라이언트의 Elixir를 생성합니다.문서의 내용에 따라 실행하면 스펙의validation 오류가 발생합니다 Documentation for the elixir Generator
참조
--skip-validate-spec
가 비활성화되면 다음 명령을 실행합니다.또한 모듈 이름openapi-generator-cli
을 지정하는 것도 요점이다.$ openapi-generator-cli generate -i https://deep-index.moralis.io/api-docs/v2/swagger.json -g elixir -o ./gen --skip-validate-spec --invoker-package Moralis
Did set selected version to 5.4.0
[main] WARN o.o.c.config.CodegenConfigurator - There were issues with the specification, but validation has been explicitly disabled.
Errors:
-attribute components.schemas.trade.items is missing
Warnings:
-Unused model: nftContractMetadataCollection
-Unused model: historicalNftTransfer
-Unused model: erc721Metadata
(省略)
################################################################################
# Thanks for using OpenAPI Generator. #
# Please consider donation to help us maintain this project 🙏 #
# https://opencollective.com/openapi_generator/donate #
################################################################################
목록 구성은 이렇게 해야 한다.$ tree -L 2
.
├── README.md
├── apps
│ ├── gen
│ ├── moralis
│ └── openapitools.json
├── config
│ └── config.exs
└── mix.exs
4 directories, 4 files
생성된 코드를 보세요.
API의 용도로 어떤 주소에 링크된 NFC 일람표를 얻으려고 합니다.그 코드 좀 봐.
이런 문서를 만들었다
Moralis
.Gets the NFTs owned by a given address
Gets NFTs owned by the given address * The response will include status [SYNCED/SYNCING] based on the contracts being indexed. * Use the token_address param to get results for a specific contract only * Note results will include all indexed NFTs * Any request which includes the token_address param will start the indexing process for that NFT collection the very first time it is requested
## Parameters
- connection (Moralis.Connection): Connection to server
- address (String.t): The owner of a given token
- opts (KeywordList): [optional] Optional parameters
- :chain (Moralis.Model.ChainList.t): The chain to query
- :format (String.t): The format of the token id
- :offset (integer()): offset
- :limit (integer()): limit
- :token_addresses ([String.t]): The addresses to get balances for (Optional)
- :cursor (String.t): The cursor returned in the last response (for getting the next page)
## Returns
{:ok, Moralis.Model.NftOwnerCollection.t} on success
{:error, Tesla.Env.t} on failure
에 대응하는 코드는 다음과 같다apps/gen/lib/moralis/api/account.ex
.스펙도 좋은 정의가 있네.@spec get_nfts(Tesla.Env.client, String.t, keyword()) :: {:ok, Moralis.Model.NftOwnerCollection.t} | {:error, Tesla.Env.t}
def get_nfts(connection, address, opts \\ []) do
optional_params = %{
:"chain" => :query,
:"format" => :query,
:"offset" => :query,
:"limit" => :query,
:"token_addresses" => :query,
:"cursor" => :query
}
%{}
|> method(:get)
|> url("/#{address}/nft")
|> add_optional_params(optional_params, opts)
|> Enum.into([])
|> (&Connection.request(connection, &1)).()
|> evaluate_response([
{ 200, %Moralis.Model.NftOwnerCollection{}}
])
end
파일 다시 쓰기
생성기에서 생성한 파일을 다시 쓸 수 없지만
apps/gen/lib/moralis/api/account.ex
오류가 발생하기 때문에 mix.exs
부분은 수동으로 다시 쓸 수 있다version
등.겸사겸사 0.0.1
의 이름 샷을 적당한 이름으로 바꾸었다.diff --git a/apps/gen/mix.exs b/apps/gen/mix.exs
index 2bcb487..c38f7fc 100644
--- a/apps/gen/mix.exs
+++ b/apps/gen/mix.exs
@@ -1,9 +1,9 @@
-defmodule Moralis.Mixfile do
+defmodule Moralis.Gen.Mixfile do
use Mix.Project
def project do
- [app: :moralis,
- version: "2",
+ [app: :gen,
+ version: "0.0.1",
elixir: "~> 1.6",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
diff --git a/apps/moralis/mix.exs b/apps/moralis/mix.exs
index a75adcf..c2d36d6 100644
--- a/apps/moralis/mix.exs
+++ b/apps/moralis/mix.exs
@@ -1,4 +1,4 @@
-defmodule Moralis.MixProject do
+defmodule Moralis.Core.MixProject do
use Mix.Project
def project do
클라이언트 모듈 만들기
생성된 구현을 사용하여 API에 액세스하는 클라이언트 코드를 씁니다
Mix.Project
.생성된 구현에서 전달된apps/moralis/lib/moralis.ex
을 사용하여 API에 접근하기 때문에 환경 변수에서 API 키로 설정된 클라이언트를 읽는 코드를 썼다.defmodule Moralis do
@moduledoc """
Handle Tesla connections for Moralis.
"""
@doc """
Configure an authless client connection
# Returns
Tesla.Env.client
"""
@spec client() :: Tesla.Env.client
def client do
[
{Tesla.Middleware.BaseUrl, "https://deep-index.moralis.io/api/v2"},
{Tesla.Middleware.EncodeJson, engine: Poison},
{Tesla.Middleware.Headers, [{"x-api-key", System.get_env("MORALIS_API_KEY")}]}
]
|> Tesla.client()
end
end
또한 Tesla.Env.client
의apps/moralis
에 상기 의존고를 미리 추가한다.diff --git a/apps/moralis/mix.exs b/apps/moralis/mix.exs
index c2d36d6..18dba6b 100644
--- a/apps/moralis/mix.exs
+++ b/apps/moralis/mix.exs
@@ -28,6 +28,8 @@ defmodule Moralis.Core.MixProject do
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"},
# {:sibling_app_in_umbrella, in_umbrella: true}
+ {:tesla, "~> 1.2"},
+ {:poison, "~> 3.0"}
]
end
end
API 클라이언트 실행
환경 변수Moralis Admin에서 획득할 수 있는 API 키를 설정합니다.
$ export MORALIS_API_KEY="********************"
이후 iex로 시작하면 다음과 같이 실행됩니다.여기서 이더 eum에 있는 나의 주소mix.exs
가 링크된 이더 eum의 메인 네트워크에 있는 NFFT의 일람을 얻었다.$ iex -S mix
iex(1)> Moralis.client |> Moralis.Api.Account.get_nfts("0xC8cFA9Ab96B9e78961607d485c50135059C84840", chain: :eth, format: :decimal)
21:45:43.419 [warning] Description: 'Authenticity is not established by certificate path validation'
Reason: 'Option {verify, verify_peer} and cacertfile/cacerts is missing'
{:ok,
%Moralis.Model.NftOwnerCollection{
cursor: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3aGVyZSI6eyJvd25lcl9vZiI6IjB4YzhjZmE5YWI5NmI5ZTc4OTYxNjA3ZDQ4NWM1MDEzNTA1OWM4NDg0MCJ9LCJsaW1pdCI6NTAwLCJvZmZzZXQiOjUwMCwib3JkZXIiOltbInRyYW5zZmVyX2luZGV4IiwiREVTQyJdXSwicGFnZSI6MSwia2V5IjoiMTQxNzcwMDguMzcuNTUuMCIsImlhdCI6MTY0NzQzNDc0M30.HfVwM7LtsZ6M1vY75lnHM7cLcrkKOmRlpDYrWyVCGTY",
page: 0,
page_size: 500,
result: [
%Moralis.Model.NftOwner{
amount: "1",
block_number: "14255778",
block_number_minted: "14255778",
contract_type: "ERC721",
metadata: "{\"is_normalized\":true,\"name\":\"antipop.eth\",\"description\":\"antipop.eth, an ENS name.\",\"attributes\":[{\"trait_type\":\"Created Date\",\"display_type\":\"date\",\"value\":null},{\"trait_type\":\"Length\",\"display_type\":\"number\",\"value\":7},{\"trait_type\":\"Registration Date\",\"display_type\":\"date\",\"value\":1645531685000},{\"trait_type\":\"Expiration Date\",\"display_type\":\"date\",\"value\":1803316445000}],\"name_length\":7,\"url\":\"https://app.ens.domains/name/antipop.eth\",\"version\":0,\"background_image\":\"https://metadata.ens.domains/mainnet/avatar/antipop.eth\",\"image_url\":\"https://metadata.ens.domains/mainnet/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/0x681d2af5f952f2f3ced409b235e8b9ba1516133c8496c650394a5793562824e1/image\"}",
name: "",
owner_of: "0xc8cfa9ab96b9e78961607d485c50135059c84840",
symbol: "",
synced_at: "2022-02-24T20:10:07.244Z",
token_address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
token_id: "47092071322328660070279121323087064708284557536712030821400426890975974532321",
token_uri: "https://metadata.ens.domains/mainnet/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/47092071322328660070279121323087064708284557536712030821400426890975974532321"
},
%Moralis.Model.NftOwner{
amount: "1",
block_number: "14246649",
block_number_minted: "14246649",
contract_type: "ERC721",
metadata: "{\n \"name\": \"Community Statement on \\\"NFT art\\\"\",\n \"description\": \"This is an NFT indicating that you have signed the Community Statement on \\\"NFT art\\\".\\n\\nWebsite: [https://nft-art-statement.github.io](https://nft-art-statement.github.io)\\n\\nPDF: [https://ipfs.io/ipfs/Qmbuc7FMZ2qsUjSMtTG6FoD6sAigCzS9AyJUtQF2cMX4Qe](https://ipfs.io/ipfs/Qmbuc7FMZ2qsUjSMtTG6FoD6sAigCzS9AyJUtQF2cMX4Qe)\\n\\nOriginal image script: [https://openprocessing.org/sketch/1491110](https://openprocessing.org/sketch/1491110)\",\n \"image\": \"https://ipfs.io/ipfs/QmURcYa9U1juYWTQaeNe2Cj9Xbxt6yXuZfx2G9XqhbGD7k\",\n \"external_url\": \"https://nft-art-statement.github.io\"\n}",
name: "Community Statement on NFT art",
owner_of: "0xc8cfa9ab96b9e78961607d485c50135059c84840",
symbol: "CSNA",
synced_at: "2022-02-21T02:06:51.280Z",
token_address: "0x01a45dfef5fc495f1b4c146319b79808be464dba",
token_id: "1146429188785820425206666927417020747748991322176",
token_uri: "https://ipfs.io/ipfs/QmXtwT89TTySmJYpvU9mNWi46Ro44x3pT5yh9m6yFN7Uy4"
},
%Moralis.Model.NftOwner{
amount: "1",
block_number: "14218466",
block_number_minted: "14218466",
contract_type: "ERC1155",
metadata: "{\"name\":\"yellow tent\",\"description\":null,\"external_link\":null,\"image\":\"https://lh3.googleusercontent.com/AuRzNcrrInhkOIG6oqxALSM2Skn1OiOlp9tZyupx59zP-T50AaiNeydvsFLH2BhvIp0wJOtqWMJeJZ7QD4Xhlpl9HAHsJA6hfnX_2w\",\"animation_url\":null}",
name: "OpenSea Shared Storefront",
owner_of: "0xc8cfa9ab96b9e78961607d485c50135059c84840",
symbol: "OPENSTORE",
synced_at: "2022-02-16T17:28:39.722Z",
token_address: "0x495f947276749ce646f68ac8c248420045cb7b5e",
token_id: "73836485752685965752355914628923343070930493146497138125618145467993293848577",
token_uri: "https://api.opensea.io/api/v1/metadata/0x495f947276749Ce646f68AC8c248420045cb7b5e/0xa33df84efd75309ae7ceb5aea44e1c7c02d98f4b000000000000010000000001"
},
%Moralis.Model.NftOwner{
amount: "1",
block_number: "14177008",
block_number_minted: "14177008",
contract_type: "ERC721",
metadata: "{\"is_normalized\":true,\"name\":\"kentarokuribayashi.eth\",\"description\":\"kentarokuribayashi.eth, an ENS name.\",\"attributes\":[{\"trait_type\":\"Created Date\",\"display_type\":\"date\",\"value\":null},{\"trait_type\":\"Length\",\"display_type\":\"number\",\"value\":18},{\"trait_type\":\"Registration Date\",\"display_type\":\"date\",\"value\":1644478257000},{\"trait_type\":\"Expiration Date\",\"display_type\":\"date\",\"value\":1802263017000}],\"name_length\":18,\"url\":\"https://app.ens.domains/name/kentarokuribayashi.eth\",\"version\":0,\"background_image\":\"https://metadata.ens.domains/mainnet/avatar/kentarokuribayashi.eth\",\"image_url\":\"https://metadata.ens.domains/mainnet/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/0xcb266aacf362d37fef19506ce033febea8121aa26f8874a71703c26158a69b01/image\"}",
name: "",
owner_of: "0xc8cfa9ab96b9e78961607d485c50135059c84840",
symbol: "",
synced_at: "2022-02-23T15:28:07.577Z",
token_address: "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
token_id: "91887384698719783598076195110397135275850003826252571321438245958937884400385",
token_uri: "https://metadata.ens.domains/mainnet/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/91887384698719783598076195110397135275850003826252571321438245958937884400385"
}
],
status: "SYNCED",
total: 4
}}
끝말
위에서 설명한 대로 API 클라이언트를 간단히 생성하고 원하는 결과를 API에서 얻을 수 있습니다.다음 단계는 GiitHub Actions 등을 통해 OpenAPI 모드에서 온 클라이언트를 자동화하는 것이지만 위와 같이 잘못될 수 있어 이번엔 그러지 못했다.만약 그 방면이 해결된다면, 나는 한번 해 보고 싶다.
Reference
이 문제에 관하여(OpenAPI Generator에서 Elixir 기반 Moralis API 클라이언트 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/kentarok/articles/4e804864aa22c4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)