Skip to content

Repository files navigation

Parameterize

Serialize object to API parameters using convenience property wrapper.

Useful to generate query items for URLComponents when build URLRequest

letparams=ParamSerializer().serialize(object: object)varcomponents=URLComponents()
components.host ="some.api"
components.path ="some/api/path/"
components.queryItems = params.map{URLQueryItem(name: $0.key, value:"\($0.value)")}
  • Auto infer name of param from field name, with default/snake_case or custom naming strategy
  • Nil and empty array will be remove automatically
  • Auto handle array (of any elements or elements that conform to ParamConvertible)
  • Auto expand nested params
  • Support any custom type by conforms to ParamConvertible, or simply use an in-place custom mapper
structApiParam:ParamsContainer{@Paramsvarquery:String?=nil@Paramsvarstatus:String="active"@Params("max_result")varmaxResult:Int=10@Params("date")varlimitDate:Date?=nil@Paramsvarids:[Int]=[1,2,3]}letparams=ApiParam()letserialized=ParamSerializer().serialize(object: params)print(serialized)
// ["status": "active", "max_result": 10, "ids": "1,2,3"]

Support any custom type by conforms to ParamConvertible

extensionDate:ParamConvertible{publicvarparameterValue:Any?{ISO8601DateFormatter().string(from:self)}}letparams=ApiParam(limitDate:Date(timeIntervalSince1970:1))letserialized=ParamSerializer().serialize(object: params)print(serialized)
// [..., "date": "1970-01-01T00:00:01Z"]

...or just use a custom mapper in-place

structApiParam:ParamsContainer{@Params(mapper:{iflet i = $0 {return i +1}else{returnnil}})varautoIncrement:Int?=nil}letparams=ApiParam(autoIncrement:100)letserialized=ParamSerializer().serialize(object: params)print(serialized)
// ["autoIncrement": 101]

Note: Conversion will go through custom mapper first, if the returned value also conforms to ParamConvertible then it will be converted again using the ParamConvertible implementation.

Note: For enum with raw value, currently there's no easy way to automatically serialize its raw value. So you will still have to conform to ParamConvertible, but you don't have to write the parameterValue implementation.

Nested params will be expanded if also conforms to ParamsContainer

structParams:ParamsContainer{@Paramsvarquery:String="search"varfilter:NestedParams=.init()}structNestedParams:ParamsContainer{@Paramsvarname:String="tux"}letparams=Params()letserialized=ParamSerializer().serialize(object: params)print(serialized)
// ["query": "search", "name": "tux"]

Naming strategy

structApiParam:ParamsContainer{@ParamsvarthisShouldBeSnakeCase:Int=0}letparams=ApiParam()letconfig=ParamSerializer.Config(namingStrategy:SerializerNamingStrategy.convertToSnakeCase)letserialized=ParamSerializer(config: config).serialize(object: params)print(serialized)
// ["this_should_be_snake_case": 0]
  • Any custom naming strategy can be done by conforming to NamingStrategy
classUppercaseNamingStrategy:NamingStrategy{publicfunc name(from fieldName:String)->String{return fieldName.uppercased()}}letparams=ApiParam()letconfig=ParamSerializer.Config(namingStrategy:UppercaseNamingStrategy())letserialized=ParamSerializer(config: config).serialize(object: params)print(serialized)
// ["THISSHOULDBESNAKECASE": 0]

About

Serialize object to API parameters using convenience property wrapper

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages