Skip to content
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

text/event-stream not supported #1375

Open
rome-user opened this issue Dec 24, 2024 · 1 comment
Open

text/event-stream not supported #1375

rome-user opened this issue Dec 24, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@rome-user
Copy link

What version of ogen are you using?

$ go list -m github.com/ogen-go/ogen
github.com/ogen-go/ogen v1.8.1

Can this issue be reproduced with the latest version?

Yes

What did you do?

Consider the following schema. Save it as openapi.yaml.

openapi: 3.0.0
info:
  title: Example API
  version: "1.0"
paths:
  /events:
    get:
      summary: SSE example
      responses:
        "200":
          description: OK
          content:
            text/event-stream:
              schema:
                type: string

Run the following terminal commands

$ go mod init repro
$ go get github.com/ogen-go/ogen/cmd/ogen
$ go run github.com/ogen-go/ogen/cmd/ogen --target gen/api -package api --clean openapi.yaml
$ go mod tidy

Create a main.go file with the following contents.

Click to view server implementation
package main

import (
	"context"
	"io"
	"log"
	"net/http"
	"time"

	"repro/api"
)

func main() {
	srv, err := api.NewServer(&service{})
	if err != nil {
		log.Fatal(err)
	}

	if err := http.ListenAndServe(":8080", srv); err != nil {
		log.Fatal(err)
	}
}

type service struct{}

func (s *service) EventsGet(ctx context.Context) (api.EventsGetOK, error) {
	r, w := io.Pipe()

	go func() {
		defer w.Close()
		for ctx.Err() == nil {
			select {
			case <-ctx.Done():
				return
			case <-time.After(1 * time.Second):
				w.Write([]byte("data: ping\n\n"))
			}
		}
	}()

	return api.EventsGetOK{Data: r}, nil
}

Finally, start the server.

$ go run main.go

What did you expect to see?

Client can stream the response. e.g.

$ curl -N http://localhost:8080/events
data: ping
data: ping
...

What did you see instead?

The generated code in oas_response_encoders_gen.go looks like the following.

Click to view generated code
func encodeEventsGetResponse(response EventsGetOK, w http.ResponseWriter, span trace.Span) error {
	w.Header().Set("Content-Type", "text/event-stream")
	w.WriteHeader(200)
	span.SetStatus(codes.Ok, http.StatusText(200))

	writer := w
	if _, err := io.Copy(writer, response); err != nil {
		return errors.Wrap(err, "write")
	}

	return nil
}

The call to io.Copy prevents streaming of response. This results in clients not receiving data.

@rome-user rome-user added the bug Something isn't working label Dec 24, 2024
@gedw99
Copy link

gedw99 commented Jan 22, 2025

Your trying to do sync push ?

I am also doing protocol buffers to open ali for pull and push ( over open api ).

Thee is a thing called asyncapi that is designed for openapi but for async . It’s got many more foot guns though .

Would love to know your use case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants