이 튜토리얼은 NammaYatri의 NammaDSL(도메인 특정 언어)을 이해하고 사용하는 데 대한 포괄적인 가이드를 제공합니다. YAML 파일 생성, 코드 생성, 컴파일은 물론 API 및 스토리지 정의를 위한 구문도 다룹니다.
위치 : 작업 중인 모듈의 spec
폴더 내에 YAML 파일을 생성합니다. 예를 들어 rider-app
에서 작업하는 경우 경로는 다음과 같습니다.
rider-platform/rider-app/spec
정의하는 사양 유형에 따라 파일을 API
또는 Storage
폴더에 배치할 수 있습니다.
코드 생성 : YAML 파일을 정의한 후 다음 명령을 실행하여 코드를 생성합니다.
, run-generator
이 명령은 SQL 쿼리뿐만 아니라 src-read-only
디렉터리에 Haskell Beam, 쿼리, 도메인 파일을 생성합니다.
중요 참고 사항 : 이 명령은 새롭거나 변경된 사양 파일만 생성합니다. 이는 사양 파일의 현재 해시를 가져오고 HEAD 커밋의 파일 해시와 비교하여 수행됩니다.
, run-generator --all
모든 사양 파일을 생성하려면 "--all" 인수를 사용하세요.
컴파일 : 다음을 사용하여 코드를 컴파일합니다.
cabal build all
imports
: 사전 정의된 유형을 가져오는 데 사용됩니다.
importPackageOverrides
: 가져오기 패키지를 재정의하는 데 사용됩니다.
module
: 모듈의 이름을 지정합니다.
참고: 대시보드 API의 경우 모듈의 모든 API에는 동일한 API 접두사가 있으며 기본적으로 module
은 Camel Case로 변환됩니다.
apiPrefix
: 기본 및 도우미 대시보드 API에 대한 기본 API 접두사를 덮어씁니다(선택 사항, 대시보드에만 해당).
참고: apiPrefix
및 helperApiPrefix
에는 빈 값 ""
이 허용됩니다. 이는 API 접두사가 없음을 의미합니다.
helperApiPrefix
: 도우미 대시보드 API에 대한 API 접두사를 덮어씁니다(선택 사항, 대시보드에만 해당).
types
: API에 대한 요청 및 응답 유형을 정의합니다. 이 필드는 선택 사항입니다. Storage DSL의 복합 유형과 동일합니다. 유형은 다음 형식으로 정의됩니다.
{TypeName}:
- {field1}: {field1Type}
- {field2}: {field2Type}
- derive: {Any extra derivation}
참고: 이전 구문은 필드 순서를 유지하지 않으며 더 이상 사용되지 않습니다.
{TypeName}:
{field1}: {field1Type}
{field2}: {field2Type}
derive: {Any extra derivation}
Enum 유형은 다음과 같이 정의할 수 있습니다.
{TypeName}:
- enum: {enum1},{enum2}
- derive: {Any extra derivation}
데이터 대신 새로운 유형이나 유형을 만들려면 recordType: NewType | Data (Default) | Type
{TypeName}:
- recordType: NewType
- {fieldName}: {fieldType}
- derive: {Any extra derivation}
{TypeName}:
- recordType: Type
- type: {fieldType}
기본 HideSecrets 인스턴스를 생성하려면 derive
키워드(대시보드에만 해당)를 사용하세요.
{TypeName}:
- {fieldName}: {fieldType}
- derive: "'HideSecrets"
apis
: 다음 형식의 모든 API를 포함합니다.
{httpMethod}
(HTTP 메서드 GET | POST | PUT | DELETE) endpoint
: API 경로
/path1/path2/{pathParam1}/path3/{pathParam2}
참고: 경로 매개변수 유형은 아래 매개변수 부분에서 언급되어야 합니다.
name
: API 이름입니다. 때로는 두 개의 서로 다른 API가 경로에서 자동 생성된 동일한 API 이름을 가지므로 덮어쓸 수 있습니다(선택 사항).
참고: 기존 API의 apiName
변경할 때는 주의하세요. apName
변경되면 Endpoint
및 UserActonType
생성도 변경되므로 이전 데이터를 다음과 같이 마이그레이션해야 합니다.
migrate:
endpoint: <oldEndpoint>
userActionType: <oldUserActionType>
일반적으로 <oldEndpoint>
및 <oldUserActionType>
은 다음 형식에서 동일한 값입니다.
PROVIDER_MANAGEMENT/BOOKING/POST_BOOKING_CANCEL_ALL_STUCK
response
:
type
: 응답 유형 request
:
type
: 요청 유형(선택 사항) multipart
:
type
: 멀티파트 요청의 경우 요청 유형(선택 사항) auth
: 인증 방식(기본값: TokenAuth)
query
: 쿼리 매개변수 목록
- {queryParam1}: {queryParam1Type}
참고: 이전 구문은 매개변수 순서를 유지하지 않으므로 더 이상 사용되지 않습니다.
{queryParam1}: {queryParam1Type}
mandatoryQuery
: 필수 쿼리 매개변수 목록
- {mandatoryQueryParam1}: {mandatoryQueryParam1Type}
참고: 이전 구문은 매개변수 순서를 유지하지 않으므로 더 이상 사용되지 않습니다.
{mandatoryQueryParam1}: {mandatoryQueryParam1Type}
params
: 경로 매개변수 목록
{pathParam1}: {pathParam1Type}
{pathParam2}: {pathParam2Type}
headers
: 헤더 목록
headers:
- {header1}: {headerType1}
- {header2}: {headerType2}
helperApi
: 기본 API와 동일한 형식의 대시보드 도우미 API를 반복적으로 포함합니다(선택 사항, 대시보드에만 해당).
validation
: 요청 유효성 검사 기능에 대한 정규화된 이름(선택 사항)
예:
imports : {}
module : Sos
types :
SosRes :
- sosId : Id Sos
SosDetailsRes :
- sos : Maybe Sos
SosReq :
- flow : SosType
- rideId : Id Ride
SosUpdateReq :
- status : SosStatus
- comment : Maybe Text
apis :
# GET /sos/getDetails
- GET :
endpoint : /sos/getDetails/{rideId}
auth : TokenAuth
params :
rideId : Id Ride
response :
type : API.Types.UI.Sos.SosDetailsRes
# # POST /sos/{sosId}/status
- POST :
endpoint : /sos/{sosId}/status
auth : TokenAuth RIDER_TYPE
params :
sosId : Id Sos
request :
type : API.Types.UI.Sos.SosUpdateReq
response :
type : Kernel.Types.APISuccess.APISuccess
auth: ApiAuth DRIVER_OFFER_BPP_MANAGEMENT DRIVERS LIST
imports
: 사전 정의된 유형을 가져오는 데 사용됩니다. 자세히 보기{dataTypeName}
: 모듈의 이름을 지정합니다. tableName
: 테이블의 선택적 이름. 정의되지 않은 경우 dataTypeName
의 snake_case를 사용합니다.
fields
: Haskell 유형의 테이블의 모든 필드를 나열합니다. 자세히 보기
constraints
: PrimaryKey | 보조키 | 널이 아님 | 자동 증가
importPackageOverrides
: 가져오기 패키지를 재정의하는 데 사용됩니다.
types
: API 유형과 유사한 사용자 정의 유형입니다. 자세히 보기
derives
: 기본 데이터 유형의 파생을 재정의합니다.
derives : " Show,Eq,Ord "
beamType
: 지정된 데이터 유형에 대한 사용자 정의 빔 유형입니다. 자세히 보기
beamFields
: 사용자 정의 빔 필드 이름을 변경하거나 빔사이드에 뭔가 다른 것을 적용하려는 경우 사용합니다. 자세히 보기
beamInstance
: 이 필드를 사용하여 필요한 빔 인스턴스를 언급할 수 있습니다.
sqlType
: 필드에 대한 사용자 정의 SQL 유형입니다. 자세히 보기
default
: 필드의 기본 SQL 값(있는 경우)
fields :
scheduleTryTimes : ' [Int] '
tripCategory : Text
default :
tripCategory : " 'All' "
scheduleTryTimes : " '{1800, 900, 300}' "
queries
: 테이블에 대한 모든 Beam 쿼리입니다. 자세히 보기
cachedQueries:
테이블에 대해 캐시된 쿼리입니다. 자세히 보기
fromTType
: 해당되는 경우 필드의 FromTType입니다. 자세히 보기
toTType
: 해당되는 경우 필드의 ToTType입니다. 자세히 보기
excludedFields
: 데이터 유형에 자동으로 추가되는 MerchantId, MerchantOperatingCityId, CreatedAt 및 업데이트된At와 같은 몇 가지 공통 필드가 있습니다. 제거하려면 이것을 사용하십시오.
excludedFields :
- merchantOperatingCityId
- merchantId
extraIndexes
: 추가 인덱스
extraOperations
: 추가 작업 자세히 보기
가져오기에 모듈 이름을 제공해야 합니다.
imports :
Merchant : Domain.Types.Merchant
FRFSSearch : Domain.Types.FRFSSearch
참고: 이러한 공통 유형은 자동으로 가져오기되므로 가져오지 않고도 직접 사용할 수 있습니다.
Text -> Kernel.Prelude
Maybe -> Kernel.Prelude
Double -> Kernel.Prelude
TimeOfDay -> Kernel.Prelude
Day -> Data.Time.Calendar
Int -> Kernel.Prelude
Bool -> Kernel.Prelude
Id -> Kernel.Types.Id
ShortId -> Kernel.Types.Id
UTCTime -> Kernel.Prelude
Meters -> Kernel.Types.Common
HighPrecMeters -> Kernel.Types.Common
Kilometers -> Kernel.Types.Common
HighPrecMoney -> Kernel.Types.Common
Seconds -> Kernel.Types.Common
imports:
DataType1: Domain.Types.DataType1
패키지를 변경하려면:
importPackageOverrides:
Domain.Types.DataType1: dashboard-api
Haskell에서 생성된 가져오기:
import "dashboard-api" Domain.Types.DataType1
때로는 동일한 패키지에서 생성할 때 패키지 재정의를 건너뛰어야 할 수도 있습니다. 그런 다음 dhall
구성에서 패키지 매핑을 지정해야 합니다.
, _packageMapping =
[ { _1 = GeneratorType. API_TYPES , _2 = " dashboard-api " }
{ _1 = GeneratorType. SERVANT_API , _2 = " rider-app " }
]
API_TYPES
에 대해 Haskell에서 생성된 가져오기:
import "this" Domain.Types.DataType1
SERVANT_API
에 대해 haskell에서 생성된 가져오기:
import "dashboard-api" Domain.Types.DataType1
필드 섹션에서 필드 이름과 해당 Haskell 유형을 언급하세요.
imports : {}
LmsModule :
tableName : lms_module
fields :
id : Id LmsModule
merchantOperatingCityId : Id MerchantOperatingCity
category : LmsCategory
createdAt : UTCTime
updatedAt : UTCTime
duration : Int
noOfVideos : Int
rank : Int
variant : Maybe Variant
moduleCompletionCriteria : ModuleCompletionCriteria
방금 가져온 단순 필드 유형의 경우 특정 빔 유형을 언급하지 않는 한 빔 측면에도 복사됩니다.
필드가 복합 유형인 경우 특정 빔 유형을 언급하지 않는 한 빔 측면에서 반복적으로 분할됩니다.
Id, ShortId의 경우 Beam Type은 Text로 간주됩니다.
도메인 측에서 가져온 데이터 유형을 원하고 빔 측에서 해당 ID를 원하는 경우 유형 정의와 함께 WithId 확장을 사용합니다.
fields :
field1 : Int
beamType :
field1 : Text
fields :
a : Int
b : Text
beamFields :
a : " aa "
b : " bb "
# SomeType = SomeType {
# integerValueInText :: Text,
# version :: Int
# }
import :
SomeType : Domain.Types.SomeType
Some :
fields :
id : Id Some
val : SomeType # See this is an imported type
beamFields :
val :
intValue : Int
intValueInText : Text
# We have to right the toTType and fromTType functions
toTType :
intValue : (Kernel.Prelude.read . Domain.Types.SomeType.integerValueInText)
intValueInText : Domain.Types.SomeType.integerValueInText
fromTType :
val : mkVal
data Some = Some
{ id :: Kernel.Types.Id. Id Domain.Types.Some. Some ,
val :: Domain.Types.SomeType. SomeType ,
merchantId :: Kernel.Prelude. Maybe ( Kernel.Types.Id. Id Domain.Types.Merchant. Merchant ),
merchantOperatingCityId :: Kernel.Prelude. Maybe ( Kernel.Types.Id. Id Domain.Types.MerchantOperatingCity. MerchantOperatingCity ),
createdAt :: Kernel.Prelude. UTCTime ,
updatedAt :: Kernel.Prelude. UTCTime
}
deriving ( Generic , Show , ToJSON , FromJSON , ToSchema )
data SomeT f = SomeT
{ id :: B. C f Kernel.Prelude. Text ,
intValue :: B. C f Kernel.Prelude. Int ,
intValueInText :: B. C f Kernel.Prelude. Text ,
merchantId :: B. C f ( Kernel.Prelude. Maybe ( Kernel.Prelude. Text )),
merchantOperatingCityId :: B. C f ( Kernel.Prelude. Maybe ( Kernel.Prelude. Text )),
createdAt :: B. C f Kernel.Prelude. UTCTime ,
updatedAt :: B. C f Kernel.Prelude. UTCTime
}
deriving ( Generic , B.Beamable )
beamInstance : MakeTableInstances
$ (mkTableInstances ''PersonT " person " )
beamInstance : MakeTableInstancesGenericSchema
$ (mkTableInstancesGenericSchema ''PersonT " person " )
beamInstance : MakeTableInstancesWithTModifier [("deviceOS", "device_o_s")]
$ (mkTableInstancesWithTModifier ''MetaDataT " meta_data " [( " deviceOS " , " device_o_s " )])
beamInstance : Custom mkCacParseInstace [[Table2],[Table3]]
$ (mkCacParseInstace ''MetaDataT [[ Table2 ], [ Table3 ]])
beamInstance : Custom mkCacParseInstace "table_name" [Table2] [Table3] [(a,b,c)]
beamInstance :
- MakeTableInstances
- Custom mkCacParseInstace [[Table2],[Table3]]
- Custom Tool.Something.mkSomething "abc" [(a,b,c)] [[a],[b],[c]]
$ (mkTableInstances ''PersonT " person " )
$ (mkCacParseInstace ''MetaDataT [[ Table2 ], [ Table3 ]])
$ ( Tool.Something. mkSomething ''MetaDataT " abc " [(a,b,c)] [[a],[b],[c]])
fields :
field1 : " [Int] "
sqlType :
field1 : " text[] "
toTType :
subscriberUrl : Kernel.Prelude.func1|I
gatewayUrl : showBaseUrlSimple # This function will be created in seperated file as it's not imported
registryUrl : showBaseUrl|M # This function will be created in seperated file as it's not imported
fromTType :
updatedAt : Kernel.Prelude.fromMaybe createdAt|I
isScheduled : makeSchelude
tripCategory : Kernel.Prelude.fromMaybe (Domain.Types.Common.OneWay Domain.Types.Common.OneWayOnDemandDynamicOffer)|I
fields :
isVerified : Bool
verificationUrl : Text
aadharId : Text
toTType :
isVerified : (K.B.verify aadharId verificationUrl)|E
toTType :
isVerified : K.B.verify isVerified aadharId verificationUrl)|EM
toTType :
isVerified : K.B.verify isVerified (K.B.C.isCorrectAadhar aadharId) verificationUrl)|EM
WithId: 가져온 데이터 유형의 ID를 Beam Field로 사용하려는 경우에 사용됩니다. 이는 빔 생성 쿼리에서 데이터 유형을 생성하지 않습니다.
WithCachedId: WithId와 동일하지만 유일한 차이점은 create 및 findbyId 쿼리를 Storage.CachedQuery에서 가져옵니다.*
WithIdCreate , WithCachedIdCreate: 쿼리 생성에서 데이터 유형을 생성해야 하는 경우 사용합니다. 중요: 가져온 데이터 유형에는 해당 쿼리 파일에 생성 기능이 있어야 합니다. 예:
fields :
fareParams : Maybe FareParameters|WithIdCreate
farePolicy : Maybe FarePolicy|WithCachedId
생성된 생성 쿼리:
create :: ( EsqDBFlow m r , MonadFlow m , CacheFlow m r ) => Domain.Types.Estimate. Estimate -> m ()
create tbl = do
Kernel.Prelude. whenJust tbl . fareParams Storage.Queries.FareParameters. create
createWithKV tbl
생성된 ToTType 및 FromTType 변환:
instance FromTType' Beam. Estimate Domain.Types.Estimate. Estimate where
fromTType' Beam. EstimateT { .. } = do
fareParams' <- maybe ( pure Nothing ) ( Storage.Queries.FareParameters. findById . Kernel.Types.Id. Id ) fareParamsId
farePolicy' <- maybe ( pure Nothing ) ( Storage.CachedQueries.FarePolicy. findById . Kernel.Types.Id. Id ) farePolicyId
pure $
Just
Domain.Types.Estimate. Estimate
{
fareParams = fareParams',
farePolicy = farePolicy'
}
instance ToTType' Beam. Estimate Domain.Types.Estimate. Estimate where
toTType' Domain.Types.Estimate. Estimate { .. } = do
Beam. EstimateT
{ Beam. fareParamsId = ( Kernel.Types.Id. getId . ( . id ) <$> ) fareParams,
Beam. farePolicyId = ( Kernel.Types.Id. getId . ( . id ) <$> ) farePolicy
}
통사론:
queries:
{query function name}:
kvFunction: {kv function name}
params: [field1, field2 .. ] Array of field to be updated in update queries
where:
{where clause}
orderby: {field name} (optional)
Where 절 구문:
where:
- {operator1}:
- field1
- {operator2}:
- field2
- field3
- {operator3}:
- field4
- field5
params 및 where 절에 사용되는 필드는 3가지 유형이 될 수 있습니다.
where:
not_eq
where:
not_eq:
- id: id2|B
myname|CS -> "myname"
123|CI -> 123
123|CS -> "123"
0.23|CD -> 0.23
"0.34"|CS -> "0.23"
true|CB -> True
Domain.Something.defaultValue|CIM -> Domain.Something.defaultValue (and Domain.Something is added to imports)
kvFunction: updateWithKV
params:
- status: newStatus
where:
eq:
- status: NEW|CIM
kvFunction: updateWithKV
params:
- status: Domain.Types.DataType.CONFIRMED|CIM
where:
eq:
- status: NEW|CIM
where:
and:
- eq:
- status: NEW|CIM
- id|B
where 연산자 목록:
예:
LmsModule :
fields :
id : Id LmsModule
category : LmsCategory
question : Question
field1 : Text
field2 : Text
field3 : Text
types :
LmsCategory :
enum : " Safety, Financial, Training "
QuestionType :
enum : " Maths, Physics, Chemistry "
derive : " Show "
Question :
question : Text
tp : QuestionType
derive : " Show,Eq "
queries :
findByComplexCondition :
kvFunction : findAllWithOptionsKV
where :
and :
- field1
- or :
- field2
- field3
- category
- question
orderBy : createdAt
updateQuestionById :
kvFunction : updateWithKV
params :
- question
where :
id
생성된 쿼리:
findAllWithKV
[ Se. And
[ Se. Is Beam. field1 $ Se. Eq field1,
Se. Or
[ Se. Is Beam. field2 $ Se. Eq field2,
Se. Is Beam. field3 $ Se. Eq field3
],
Se. Is Beam. category $ Se. Eq category,
Se. Is Beam. questionQuestion $ Se. Eq $ Domain.Types.LmsModule. question question,
Se. Is Beam. questionTp $ Se. Eq $ Domain.Types.LmsModule. tp question
]
]
updateQuestionById question ( Kernel.Types.Id. Id id ) = do
_now <- getCurrentTime
updateWithKV
[ Se. Set Beam. questionQuestion $ Domain.Types.LmsModule. question question,
Se. Set Beam. questionTp $ Domain.Types.LmsModule. tp question,
Se. Set Beam. updatedAt _now
]
[ Se. Is Beam. id $ Se. Eq id
]