Can not define a middleware to add an apikey to an openapi-generator project

I am. trying to play around with the sample openapi project demonstrated during WWDC 2024. I am able to get it to run clean (without middleware) but as soon as I want to define middleware I get errors. here is the code:

//
// OpenAPClient2App.swift
// OpenAPClient2

import SwiftUI

@main
struct OpenAPClient2App: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

and the content view with the failing middleware:
//
// ContentView.swift
// OpenAPClient2

import SwiftUI
import OpenAPIRuntime
import OpenAPIURLSession
import Foundation

preview {
ContentView()
}

struct AuthenticationMiddleware: ClientMiddleware {
func intercept(
_ request: HTTPRequest,
body: HTTPBody?,
baseURL: URL,
operationID: String,
next: (HTTPRequest, HTTPBody?, URL) async throws -> (HTTPResponse, HTTPBody?)
) async throws -> (HTTPResponse, HTTPBody?) {
var request = request
request.headerFields["X-API-Key"] = "test123"
return try await next(request, body, baseURL)
}
}

struct ContentView: View {
@State private var greeting = ""
@State private var yourName: String = ""
@State private var emoji = ":dotted_line_face:"
@State private var ecount = 0

var body: some View {
    VStack {
        // Greeting section
        Text("Greeting client").font(.system(size: 30))

        Spacer().frame(height: 20)

        Text(greeting).font(.system(size: 20))

        TextField("Enter your text here", text: $yourName)
            .padding()
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .padding()

        Button("Get Greeting") {
            Task {
                //try? await updateGreeting(name: yourName)
            }
            print(yourName)
        }

        Spacer().frame(height: 20)
        Text("Emoji client").font(.system(size: 30))

        Spacer().frame(height: 20)
        Text(emoji)

        TextField("Enter your score", value: $ecount, format: .number)
            .padding()
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .padding()
        
        Button(action: {
            Task {
                print ("count: \(ecount)")
                try? await updateEmoji(count:ecount)
            }
            print("Button was tapped!")
        }) {
            Text("Get Emoji")
        }
    }
    .padding()
    .buttonStyle(.borderedProminent)
}

let client: Client

init() {

    self.client = Client(
        serverURL: try! Servers.Server1.url(),
        transport: URLSessionTransport() // ,
        // middlewares: [
        //    AuthenticationMiddleware,
        // ]

    )
}


func updateEmoji(count : Int = 3 ) async throws {
    let response = try await client.getEmoji(Operations.getEmoji.Input())
    
    switch response {
    case let .ok(okResponse):
        switch okResponse.body {
        case .json(let jsonData):

            // Attempt to decode the EmojiResponse from the JSON data
            let emojiresponse = jsonData.emojis.self?.joined(separator: " ")
            print(emojiresponse!)
            emoji = emojiresponse!   // Join the emojis array into a single string and update the UI
            
        default:
            print("Unexpected body format")
            emoji = "🙉"  // Default emoji for unexpected body format
        }
    case .undocumented(statusCode: let statusCode, _):
        print("cat-astrophe: \(statusCode)")
        emoji = "🙉"  // Default emoji for undocumented status codes
    }
}

}

the open api is here:
openapi: '3.0.3'
info:
title: GreetingService
version: 1.0.0
servers:

  • url: http://127.0.0.1:8080/api
    description: Localhost deployment.
    components:
    securitySchemes:
    ApiKeyAuth:
    type: apiKey
    in: header # The API key will be passed in the request header
    name: X-API-Key # The name of the header where the API key is passed
    schemas:
    Greeting:
    type: object
    properties:
    message:
    type: string
    description: The greeting message.
    example:
    message: "Hello, world!"
    EmojiResponse:
    type: object
    properties:
    emojis:
    type: array
    items:
    type: string
    description: A list of emojis.
    paths:
    /greet:
    get:
    tags:
    - Greetings
    operationId: getGreeting
    summary: Get a personalized greeting message.
    parameters:
    - name: name
    in: query
    required: false
    description: The name used in the returned greeting.
    schema:
    type: string
    security:
    - ApiKeyAuth: # Secure this endpoint with the ApiKeyAuth scheme
    responses:
    '200':
    description: A success response with a greeting message.
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/Greeting'
    example:
    message: "Hello, John!"
    /emoji:
    get:
    tags:
    - Emojis
    operationId: getEmoji
    summary: Get a random emoji or multiple emojis.
    parameters:
    - name: count
    in: query
    required: false
    description: The number of emojis to return. Defaults to 1.
    schema:
    type: integer
    minimum: 1
    default: 1
    security:
    - ApiKeyAuth: # Secure this endpoint with the ApiKeyAuth scheme
    responses:
    '200':
    description: A response containing one or more random emojis.
    content:
    application/json:
    schema:
    $ref: '#/components/schemas/EmojiResponse'
    example:
    emojis: [":blush:", ":joy:"]

Apply security globally (optional)

security:

- ApiKeyAuth:

the errors are:
OpenAPClient2/OpenAPClient2/ContentView.swift:19:20 Cannot find type 'HTTPRequest' in scope
OpenAPClient2/OpenAPClient2/ContentView.swift:23:16 Cannot find type 'HTTPRequest' in scope
OpenAPClient2/OpenAPClient2/ContentView.swift:23:62 Cannot find type 'HTTPResponse' in scope
OpenAPClient2/OpenAPClient2/ContentView.swift:24:24 Cannot find type 'HTTPResponse' in scope

Hi @gdecuba,

try adding import HTTPTypes to the top of ContentView.swift.

Thanks that did it

1 Like