[swift-server-dev] HTTPMethod, was: Re: Next HTTP API meeting

David Waite david at alkaline-solutions.com
Thu Mar 23 16:27:20 CDT 2017

> On 23 Mar 2017, at 13:35, Logan Wright <logan at qutheory.io> wrote:
>> enum Method {
>>    case get, post, put, patch
>>    case other(String)
>> }
>> I think in addition to adding new official methods (I might be wrong here, need to double check)
> You are saying that you would add all currently RFC’ed methods to that enum, right? Remember that you can’t add additional ‘case’ values to the enum later, that wouldn’t even be API compatible.

I wouldn’t recommend an enum, mostly because there is no use in a comprehensive select, a comprehensive select is pointless anyways with an ‘other’ type, and such an enum has a larger value footprint than a String (needs to have space to identify the cases as well as have space for a string in the other case)


> I think it may be worth considering something like that:
>  struct HTTPMethod {
>    // can/should be done as a RawRepresentable? Don’t know :-)
>    static let GET : UInt8 = 0
>    … all we know at the time …
>    let code : UInt8
>    func == (lhs: HTTPMethod, rhs: String)
>>  }

I’d recommend something closer to Notification.Name, with a String rawValue. Adding a new numerical rawValue would require any custom methods to be registered with the parser.

public struct Method : RawRepresentable, Equatable, Hashable, Comparable {
  public let rawValue: String
  public init(rawValue: String) { … }
  // …

  public static let get:Method = Method(rawValue: “GET”)
  public static let post:Method = Method(rawValue: “POST”)
  // ...

The optimizer will make sure such a Method struct uses no more space or code complexity than referencing String directly.

When I’ve made such method types in the past implementing HTTP servers in other languages, I made Method a protocol and added a registration step to support method lookup by string. This was because the Method protocol also represented the characteristics of a new method in processing by the server itself (safeness/idempotency,  cachability of response,  how HEAD doesn’t send a body, how GET doesn’t require content-length, how OPTIONS supports OPTIONS *, etc). I then took the list of methods registered with the IANA at the time and registered all of them by default (as well as adding a test-time check to verify the IANA page hadn’t changed).

> P.S.: Does Swift 4 propose any way to intern strings? That is also a nice way to do this kind of thing and still get decent performance (essentially what Cocoa Swift does for NSNotification names).

The string data is not duplicated on assignment, but reference counted. If everyone references the string from the same place, there will only be a single copy of the string data (with a very high reference count).

Java and C# intern() actually copies the string data to a table (basically a weak map), and returns a String object pointing to that data.


More information about the swift-server-dev mailing list