このチュートリアルは、NammaYatri のドメイン固有言語 (NammaDSL) を理解し、使用するための包括的なガイドを提供します。 YAML ファイルの作成、コード生成、コンパイルに加え、API とストレージを定義するための構文についても説明します。
場所: 作業しているモジュールのspec
フォルダー内に YAML ファイルを作成します。たとえば、 rider-app
で作業している場合、パスは次のようになります。
rider-platform/rider-app/spec
定義している仕様の種類に応じて、ファイルをAPI
またはStorage
フォルダー内に配置できます。
コード生成: YAML ファイルを定義した後、次のコマンドを実行してコードを生成します。
, run-generator
このコマンドは、SQL クエリだけでなく、Haskell Beam、クエリ、ドメイン ファイルをsrc-read-only
ディレクトリに生成します。
重要な注意: このコマンドは、新規または変更された仕様ファイルのみを生成します。これは、仕様ファイルの現在のハッシュを取得し、HEAD コミットのファイル ハッシュと比較することによって行われます。
, run-generator --all
すべての仕様ファイルを生成するには、「--all」引数を使用します。
コンパイル: 以下を使用してコードをコンパイルします。
cabal build all
imports
: 事前定義されたタイプをインポートするために使用されます。
importPackageOverrides
: インポート パッケージをオーバーライドするために使用されます。
module
: モジュールの名前を指定します。
注:ダッシュボード API の場合、モジュール内のすべての API は同じ API プレフィックスを持ち、デフォルトではmodule
がキャメルケースに変換されます。
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}
列挙型は次のように定義できます。
{TypeName}:
- enum: {enum1},{enum2}
- derive: {Any extra derivation}
newtype またはデータの代わりに型を作成するには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 名。場合によっては、2 つの異なる 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}
注:古い構文は params の順序を保持しないため、非推奨になります。
{queryParam1}: {queryParam1Type}
mandatoryQuery
: 必須のクエリパラメータのリスト
- {mandatoryQueryParam1}: {mandatoryQueryParam1Type}
注:古い構文は params の順序を保持しないため、非推奨になります。
{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
:主キー |セカンダリキー |非ヌル |自動インクリメント
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、updatedAt などの一般的なフィールドがいくつかあります。それらを削除するには、これを使用します。
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
configs でパッケージ マッピングを指定する必要があります。
, _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 の場合、ビームタイプはテキストとみなされます。
ドメイン側でインポートされたデータ型が必要で、ビーム側で対応する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 をビーム フィールドとして使用する場合に使用されます。これでは、ビーム作成クエリでデータ型は作成されません。
WithCachedId: WithId と同じですが、 createとfindbyIdクエリが Storage.CachedQuery からインポートされることだけが異なります。*
WithIdCreate 、 WithCachedIdCreate:作成クエリでデータ型を作成する必要がある場合にこれを使用します。重要: インポートされたデータ型には、対応するクエリ ファイルにcreate関数が含まれている必要があります。 例:
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
]