-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Complex attribute values (json, array) #4
Comments
Yes. In Felicity, you are free to return whatever you want. For example, if you use However, please consider if this is the optimal resource design. Why not have While JSON:API allows attributes to be objects, things tend to be simpler if you keep things flat. |
Hello, yes, I know that flatten structure is easier to handle, but I need a Domain specific types to be there.
But I still can't handle it. {
...
"attributes": {
"contact": "... contact ..."
}
} but when I send a {
...
"attributes": {
"contact": {
"email": "<email>",
"phone": "<phone>"
}
}
} I could not get a data - I always get the error
|
Hm, not sure what's wrong, but it may look like it infers the attribute type to be string. Could you share the Felicity code for this attribute definition, and any signatures for the functions you're using in the attribute definition? |
Well it might be the problem. TLDRI was not sure what should be the type of such attribute. So I had a Business LogicThis API is for identifying persons by contact - client send (POST) contact (json above) and gets PersonId (it would create a person if there is not one yet). So the contact should be skipped in the response. This is my codea bit simplified, but basically this ... // Domain
type PersonId = PersonId of string
type Email = Email of string
type Phone = Phone of string
type Contact =
| IsEmail of Email
| IsPhone of Phone
| IsEmailAndPhone of Email * Phone
type Identity = {
Id: PersonId
Contact: Contact
}
// Resource
let contact =
define.Attribute
.Simple()
.GetSkip(fun ctx identity ->
printfn "skip: %A" identity
Skip
)
.Set(fun (contact: obj) identity ->
printfn "set: %A (%A)" c (c.GetType())
identity
)
let post =
define.Operation
.Post(fun ctx parser ->
let require attribute =
attribute
|> parser.GetRequired
|> Hopac.Job.toAsync <@> AttributeErrors
asyncResult {
let! (contact: obj) = require contact
printfn "contact in post: %A (%A)" contact (contact.GetType())
(* let! contact =
contact
|> Contact.parseString
|> AsyncResult.ofResult <@> ParseContactError *)
// I'd like to parse contact here, but now I just create a dummy one, to make it all pass and log only
let contact = IsEmail (Email "... dummy email ...")
return {
Id = PersonId "... todo ..."
Contact = contact
}
}
|> parser.ForAsyncRes
)
.AfterCreate(fun identity -> identity) where for {
"data": {
"type": "identities",
"attributes": {
"contact": { "email": "" }
}
}
} the output is:
So when I've changed Thanks for help! |
The type used in In fact you should ideally not use a domain type directly at all, because if you do, you need to be aware that the domain object is serialized directly, and you can't rename/refactor your domain code at will without risking breaking clients. The ideal solution in your case is to create a record type for the JSON representation, e.g. type ContactDto =
{ email: string option
phone: string option } ( and then map between this DTO and whatever else you have in your domain logic. That way, you have a stable JSON representation that won't accidentally change if you refactor/rename domain stuff. You should not need to use Again though, you may want to factor If you are thinking "what would the ID of the |
Ohh.. Now I get it :) Thank you! 👍 |
Hello,
is it possible to define an attribute as a
JsonObject
or an array?I'd like to have a resource with attributes like this:
Thank you.
The text was updated successfully, but these errors were encountered: