mago3D๋ 2D ๋ฐ 3D ๋ฐ์ดํฐ๋ฅผ ์ ๋ก๋ํ๊ณ , ์ด๋ฅผ ์ต์ ํ๋ ํํ๋ก ๋ณํํ์ฌ ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด 3์ฐจ์์ผ๋ก ์๊ฐํํ ์ ์๋ ์คํ์์ค ํ๋ซํผ์ ๋๋ค. ๋ค์ํ ๊ณต๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ฝ๊ฒ ๊ด๋ฆฌํ๊ณ ์๊ฐํํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ๋์ ๊ณํ, ์์ค ๊ด๋ฆฌ, ์ฌ๋ ๊ด๋ฆฌ ๋ฑ ์ฌ๋ฌ ๋ถ์ผ์์ ํ์ฉ๋ ์ ์์ต๋๋ค.
์ฃผ์๋ชฉ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ฐ์ดํฐ์ ํตํฉ ์๊ฐํ: 2D ๋ฐ 3D ๊ณต๊ฐ ๋ฐ์ดํฐ๋ฅผ ์น ํ๊ฒฝ์์ ํตํฉ์ ์ผ๋ก ์๊ฐํํ์ฌ ๋ณต์กํ ์ ๋ณด๋ฅผ ์ง๊ด์ ์ผ๋ก ์ดํดํ ์ ์๊ฒ ํฉ๋๋ค.
- ๋ฐ์ดํฐ ์ต์ ํ ๋ฐ ๋ณํ: ์ฌ์ฉ์๊ฐ ์ ๋ก๋ํ ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ์น ํ๊ฒฝ์์ ํจ์จ์ ์ผ๋ก ๋ ๋๋งํ ์ ์๋๋ก ์ต์ ํ๋ 3D ํ์์ผ๋ก ๋ณํํฉ๋๋ค.
mago3D API๋ ์ฌ์ฉ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ์
๋ก๋, ๊ด๋ฆฌ ๋ฐ ์๊ฐํํ๋ ๋ฐ ํ์ํ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
API๋ ํฌ๊ฒ ์ธ ๊ฐ์ง
์ดํ๋ฆฌ์ผ์ด์
์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ, ๊ฐ ์ดํ๋ฆฌ์ผ์ด์
์ ํน์ ํ ๊ธฐ๋ฅ์ ๋ด๋นํฉ๋๋ค:
- ๋ฐ์ดํฐ ๊ทธ๋ฃน ๊ด๋ฆฌ: ๊ทธ๋ฃน ์ถ๊ฐ, ์์ , ์ญ์ , ๋ชฉ๋ก ์กฐํ ๋ฐ ๊ทธ๋ฃน๋ณ ๋ฐ์ดํฐ ์กฐํ ๊ธฐ๋ฅ ์ ๊ณต
- ๋ฐ์ดํฐ ๊ด๋ฆฌ: 2D/3D ๋ฐ์ดํฐ ์ ๋ก๋, ๋ฐ์ดํฐ ๋ชฉ๋ก ์กฐํ, ๊ฒ์, ์์ ๋ฐ ์ญ์ ๊ธฐ๋ฅ์ ์ ๊ณต
- ๋ฐ์ดํฐ ๋ณํ: ์ ๋ก๋๋ ๋ฐ์ดํฐ๋ฅผ ์น ํ๊ฒฝ์์ ํจ๊ณผ์ ์ผ๋ก ๋ ๋๋งํ ์ ์๋๋ก ์ต์ ํ๋ ํ์์ผ๋ก ๋ณํ
- ๋ ์ด์ด ๊ทธ๋ฃน ๊ด๋ฆฌ: ๊ทธ๋ฃน ์ถ๊ฐ, ์์ , ์ญ์ ๋ฐ ๊ทธ๋ฃน๋ณ ๋ ์ด์ด ์กฐํ ๊ธฐ๋ฅ ์ ๊ณต
- ๋ ์ด์ด ๊ด๋ฆฌ: ๋ ์ด์ด ๋ฑ๋ก, ์์ , ์ญ์ ๋ฐ ๋ ์ด์ด ๊ถํ(๊ณต๊ฐ/๋น๊ณต๊ฐ), ์ผ์ง์ฌ๋ถ(์ผ์ง/๊บผ์ง), ์ฌ์ฉ์ฌ๋ถ(์ฌ์ฉ/๋ฏธ์ฌ์ฉ) ์ค์ ๊ธฐ๋ฅ ์ ๊ณต
- ๋ ์ด์ด ๋ฏธ๋ฆฌ๋ณด๊ธฐ: ๋ณํ๋ ๋ ์ด์ด์ ๋ฏธ๋ฆฌ๋ณผ ์ ์๋ ๊ธฐ๋ฅ ์ ๊ณต
- ๋ ์ด์ด ์คํ์ผ: ๋ฒกํฐ ๋ ์ด์ด์ ์ , ์ , ๋ฉด, ์์ฑ๋ณ ์คํ์ผ ๊ด๋ฆฌ๊ธฐ๋ฅ ์ ๊ณต
- ์ฌ์ฉ์ ๊ด๋ฆฌ: ์ฌ์ฉ์ ๊ณ์ ์์ฑ, ์์ , ์ญ์ , ์กฐํ์ ๊ฐ์ ๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ์ ๊ด๋ฆฌ ๊ธฐ๋ฅ ์ ๊ณต
- ๊ถํ ๊ด๋ฆฌ: ๊ฐ ์ฌ์ฉ์ ๊ทธ๋ฃน์ ๋ํ ์ ์ ๊ถํ ์ค์ ๊ธฐ๋ฅ ์ ๊ณต
GraphQL์ Facebook์ด ๊ฐ๋ฐํ ๋ฐ์ดํฐ ์ฟผ๋ฆฌ ์ธ์ด๋ก, API๋ฅผ ํจ์จ์ ์ผ๋ก ํธ์ถํ๊ณ ๋ฐ์ดํฐ ์์ฒญ์ ์ต์ ํํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
REST API์ ๋ฌ๋ฆฌ, GraphQL์์๋ ํด๋ผ์ด์ธํธ๊ฐ ํ์ํ ๋ฐ์ดํฐ์ ๊ตฌ์กฐ๋ฅผ ๋ช
ํํ ์ ์ํ ์ ์์ด ๊ณผ๋ํ ๋ฐ์ดํฐ ์ ์ก(over-fetching)์ด๋ ๋ถ์กฑํ ๋ฐ์ดํฐ ์ ์ก(under-fetching)์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
- ์คํค๋ง๋ GraphQL ์๋ฒ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๋ ์ญํ ์ ํฉ๋๋ค. ์คํค๋ง๋ ์ด๋ค ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ๊ณ , ๊ทธ ๋ฐ์ดํฐ๋ค ๊ฐ์ ๊ด๊ณ๊ฐ ๋ฌด์์ธ์ง, ๊ทธ๋ฆฌ๊ณ ํด๋ผ์ด์ธํธ๊ฐ ์ด๋ค ์์ฒญ์ ํ ์ ์๋์ง๋ฅผ ๋ช ํํ ์ค๋ช ํฉ๋๋ค.
- ์คํค๋ง์๋ ํ์ (Types), ์ฟผ๋ฆฌ(Queries), ๋ฎคํ ์ด์ (Mutations)์ด ํฌํจ๋์ด ์์ผ๋ฉฐ, ์ด ์คํค๋ง๋ฅผ ๋ฐํ์ผ๋ก ํด๋ผ์ด์ธํธ๋ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ ์ ์๋์ง ์ ์ ์์ต๋๋ค.
- ์ฟผ๋ฆฌ๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ ์ํด ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด๋ ๋ฐฉ์์ ๋๋ค. ์๋ฅผ ๋ค์ด, ํน์ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ์์ฒญํ ๋ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- REST์์ GET ์์ฒญ๊ณผ ์ ์ฌํ์ง๋ง, ํ์ํ ๋ฐ์ดํฐ ํ๋๋ง ์ ํํ์ฌ ์์ฒญํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์์ ์ด๋ฆ๊ณผ ์ด๋ฉ์ผ๋ง ์์ฒญํ ์ ์์ต๋๋ค. ์ฟผ๋ฆฌ ์์
query {
asset(id: "1") {
id
name
description
}
}
์ด ์ฟผ๋ฆฌ๋ ID๊ฐ 1์ธ ์์ฐ์ ID, ์ด๋ฆ, ์ค๋ช ์ ์์ฒญํฉ๋๋ค.
- ๋ฎคํ ์ด์ ์ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์์ฑ(Create), ์์ (Update), ์ญ์ (Delete)ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. REST์ POST, PUT, DELETE์ ๋น์ทํ ๊ฐ๋ ์ ๋๋ค.
- ๋ฎคํ ์ด์ ์ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ณ๊ฒฝ์ด ์ผ์ด๋ ํ, ์์ฒญํ ํด๋ผ์ด์ธํธ์๊ฒ ๋ณ๊ฒฝ๋ ๋ฐ์ดํฐ๊ฐ ๋ฐํ๋ ์ ์์ต๋๋ค. ๋ฎคํ ์ด์ ์์
mutation CreateGroup {
createGroup(input: { name: "Group 1", description: "Group 1 description" }) {
id
name
description
}
}
์ด ๋ฎคํ ์ด์ ์ ์๋ก์ด ๊ทธ๋ฃน์ ์์ฑํ๊ณ , ์์ฑ๋ ๊ทธ๋ฃน์ ID, ์ด๋ฆ, ์ค๋ช ์ ๋ฐํํฉ๋๋ค.
- GraphQL์ ๋ชจ๋ ๋ฐ์ดํฐ๋ ํ์ ์ผ๋ก ์ ์๋ฉ๋๋ค. ํ์ ์ ์คํค๋ง์์ ๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๊ตฌ์ฑํ ์ง ๋ํ๋ด๋ฉฐ, ๊ฐ ํ์ ์ ํ๋๋ฅผ ๊ฐ์ง๋ฉฐ ํ๋๋ง๋ค ๋ฐ์ดํฐ ์ ํ์ด ์์ต๋๋ค.
- ์๋ฅผ ๋ค์ด, User ํ์ ์ ์ฌ์ฉ์์ ID, ์ด๋ฆ, ์ด๋ฉ์ผ ๋ฑ์ ํ๋๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค. ํ์ ์์
type Asset {
id: ID!
name: String!
description: String
}
์ด ํ์ ์ ์๋ ID, ์ด๋ฆ, ์ค๋ช ํ๋๋ฅผ ๊ฐ์ง๋ Asset ํ์ ์ ์ ์ํฉ๋๋ค.
- GraphQL ์ฟผ๋ฆฌ์์ ํ๋๋ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ ๋จ์์ ๋๋ค. ํด๋ผ์ด์ธํธ๋ ํ์ํ ํ๋๋ง ์ ํ์ ์ผ๋ก ์์ฒญํ ์ ์์ผ๋ฉฐ, ์๋ฒ๋ ์ ํ๋ ํ๋๋ง ๋ฐํํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ถํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ง ์๊ฒ ๋ฉ๋๋ค.
- GraphQL์ ํด๋ผ์ด์ธํธ๊ฐ ์ฟผ๋ฆฌ ์ ๋ค์ํ ์กฐ๊ฑด์ ๊ฑธ์ด ๋ฐ์ดํฐ๋ฅผ ํํฐ๋งํ๊ฑฐ๋ ํ์ด์ง(ํ์ด์ง ๋จ์๋ก ๋ฐ์ดํฐ๋ฅผ ๋๋ ์ ์์ฒญ), ์ ๋ ฌ ๋ฑ์ ํ ์ ์๋ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค. ์์
query Assets {
assets(pageable: { page: 0, size: 10, sort: [CREATED_AT_DESC] }) {
items {
id
name
description
}
}
}
์ด ์ฟผ๋ฆฌ๋ assets๋ฅผ ์์ฒญํ๊ณ , ํ์ด์ง๋ค์ด์ , ์ ๋ ฌ, ํ๋ ์ ํ ๋ฑ์ ์ ์ฉํ ์์์ ๋๋ค.
- ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์ ์ก: ํด๋ผ์ด์ธํธ๋ ํ์ํ ๋ฐ์ดํฐ๋ง ์ ํํ๊ฒ ์์ฒญํ ์ ์๊ธฐ ๋๋ฌธ์, ๋ถํ์ํ ๋ฐ์ดํฐ ์ ์ก์ ์ค์ผ ์ ์์ต๋๋ค.
- ํ๋์ ์๋ํฌ์ธํธ: REST API์ ๋ฌ๋ฆฌ ์ฌ๋ฌ ์๋ํฌ์ธํธ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ , ํ๋์ ์๋ํฌ์ธํธ์์ ๋ค์ํ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ ์ ์์ต๋๋ค.
- ํ์ ์์คํ : ์คํค๋ง๋ฅผ ํตํด API์ ๊ตฌ์กฐ๊ฐ ๋ช ํํ ์ ์๋์ด ์์ด, ์์ฒญํ๋ ๋ฐ์ดํฐ์ ํ์ ์ ์ฝ๊ฒ ์ดํดํ ์ ์์ผ๋ฉฐ, ๊ฐ๋ฐ ์ค์ ์ค๋ฅ๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
-
API ์๋ํฌ์ธํธ:
{{app-server-url}}
: https://dev.localhost/app- Dataset Application:
{{app-server-url}}
/api/dataset/graphql - Layerset Application:
{{app-server-url}}
/api/layerset/graphql - Userset Application:
{{app-server-url}}
/api/userset/graphql
- Dataset Application:
-
์ธ์ฆ ๋ฐฉ๋ฒ: API ์ฌ์ฉ ์ ํ์ํ ์ธ์ฆ ๋ฐฉ์์ JWT ํ ํฐ ๋ฐฉ์ ์ ๋๋ค, ์์ ์์ฒญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
{{auth-server-url}}
/realms/{{auth-realm}}
/protocol/openid-connect/token
{{auth-server-url}}
: https://dev.localhost/auth
{{auth-realm}}
: mago3d
POST https://dev.localhost/auth/realms/mago3d/protocol/openid-connect/token
{
"grant_type": "password",
"client_id": "mago3d-front",
"username": "admin",
"password": {{admin password}}
}
{
"grant_type": "client_credentials",
"client_id": "mago3d-api",
"client_secret": {{client secret key}}
}
{
"access_token": {{access token}},
"expires_in": 35999,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "profile email"
}
- ์์ฒญ ๋ฐ ์๋ต ํ์: GraphQL ์ฟผ๋ฆฌ ๋ฐ ๋ฎคํ ์ด์ ์ ์์ฒญ ํ์๊ณผ ์๋ฒ๋ก๋ถํฐ ๋ฐ๋ ์๋ต ํ์์ ๋ํด ์ค๋ช ํฉ๋๋ค.
query Asset {
asset(id: "1") {
id
name
description
}
}
{
"data": {
"asset": {
"id": "1",
"name": "Asset 1",
"description": "This is asset 1"
}
}
}
mutation CreateGroup {
createGroup(input: { name: "Group 1", description: "Group 1 description" }) {
id
name
description
}
}
{
"data": {
"createGroup": {
"id": "1",
"name": "Group 1",
"description": "Group 1 description"
}
}
}
GraphQL ์์ฒญ์ด ์คํจํ๋ฉด, errors ํ๋๋ฅผ ํฌํจํ ์๋ต์ด ๋ฐํ๋ฉ๋๋ค.
{
"errors": [
{
"message": "AssetNotFound",
"locations": [
{
"line": 2,
"column": 5
}
],
"path": [
"asset"
],
"extensions": {
"classification": "NOT_FOUND"
}
}
],
"data": {
"asset": null
}
}
- ํ์ (Types)
- ์ฟผ๋ฆฌ (Queries)
- ๋ฎคํ ์ด์ (Mutations)
mago3D API ๋ฌธ์ ์ฐธ๊ณ
๋ฐ์ดํฐ ๋ณํ
mutation CreateProcess {
createProcess(
input: {
name: "convert 1"
source: { assetId: [1] }
context: { t3d: { inputType: FBX, recursive: true } }
}
) {
id
name
status
createdBy
createdAt
updatedBy
updatedAt
}
}
๋ฐ์ดํฐ ๋ณํ ์ํ ์กฐํ
query Process {
process(id: "1") {
id
name
context
status
}
}
๋ ์ด์ด ๋ฐํ
mutation CreateAsset {
createAsset(
input: {
name: "test"
description: "test"
context: { t3d: { dataAssetId: "1" } }
type: TILES3D
}
) {
id
name
description
type
enabled
visible
access
status
order
}
}
๋ ์ด์ด ๋ชฉ๋ก ์กฐํ
query Assets {
assets {
id
name
description
type
enabled
visible
access
status
order
properties
}
}