Skip to content

helper method to create HTTP response with code #64

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

Merged
merged 3 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ keywords = ["Swagger", "OpenAPI", "REST"]
license = "MIT"
desc = "OpenAPI server and client helper for Julia"
authors = ["JuliaHub Inc."]
version = "0.1.20"
version = "0.1.21"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
12 changes: 12 additions & 0 deletions docs/src/userguide.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ Optional middlewares can be one or more of:
The order in which middlewares are invoked is:
`init |> read |> pre_validation |> validate |> pre_invoke |> invoke |> post_invoke`

## Responses

The server APIs can return the Julia type that is specified in the OpenAPI specification. The response is serialized as JSON and sent back to the client. The default HTTP response code used in this case is 200.

To return a custom HTTP response code, the server API can return a `HTTP.Response` instance directly. The OpenAPI package provides a overridden constructor for `HTTP.Response` that takes the desired HTTP code and the Julia struct that needs to be serialized as JSON and sent back to the client. It also sets the `Content-Type` header to `application/json`.

```julia
HTTP.Response(code::Integer, o::APIModel)
```

Structured error messages can also be returned in similar fashion. Any uncaught exception thrown by the server API is caught and converted into a `HTTP.Response` instance with the HTTP code set to 500 and the exception message as the response body.

## Streaming Responses

Some OpenAPI implementations implement streaming of responses by sending more than one items in the response, each of which is of the type declared as the return type in the specification. E.g. the [Twitter OpenAPI specification](https://api.twitter.com/2/openapi.json) that keeps sending tweets in JSON like this forever:
Expand Down
4 changes: 4 additions & 0 deletions src/server.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ function to_param(T, source::Vector{HTTP.Forms.Multipart}, name::String; require
end
end

function HTTP.Response(code::Integer, o::APIModel)
return HTTP.Response(code, [Pair("Content-Type", "application/json")], to_json(o))
end

server_response(resp::HTTP.Response) = resp
server_response(::Nothing) = server_response("")
server_response(ret) =
Expand Down
10 changes: 10 additions & 0 deletions test/client/allany/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ include(joinpath(@__DIR__, "AllAnyClient", "src", "AllAnyClient.jl"))
using .AllAnyClient
using Test
using JSON
using HTTP
using OpenAPI
using OpenAPI.Clients
import OpenAPI.Clients: Client
Expand Down Expand Up @@ -146,4 +147,13 @@ function test_debug()
end
end

function test_http_resp()
resp = HTTP.Response(200, dog)

@test resp.status == 200
@test resp.headers == ["Content-Type" => "application/json"]
json = JSON.parse(String(copy(resp.body)))
@test pet_equals(OpenAPI.Clients.from_json(M.Dog, json), dog)
end

end # module AllAnyTests
4 changes: 4 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,8 @@ include("forms/forms_client.jl")
run_tests_with_servers && servers_running && stop_server(8081, ret, out)
end
end

@testset "Helper Methods" begin
AllAnyTests.test_http_resp()
end
end