Kay
Kay

Reputation: 19660

Tapir - Method too large

Im defining endpoints using tapir however i get the following compilation error.

[info] Compiling 3 Scala sources to /endpoints/target/scala-2.13/classes ... [error] Error while emitting/endpoints/Session$ [error] Method too large: endpoints/Session$. ()V [error] one error found [error] (endpoints / Compile / compileIncremental) Compilation failed [error] Total time: 26 s, completed 12-Mar-2020 15:29:54

 val manualReviewEndpoint: Endpoint[(SessionModel.AuthToken, SessionModel.ManualReview.ManualReviewRequest), ErrorsModel.FailureResponse, SessionModel.ManualReview.ManualReviewResponse, Nothing] = endpoint
    .tag("Sessions")
    .description("Triggers manual review for sessions within date range")
    .post
    .in(auth.bearer)
    .in("sessions" / "trigger-review")
    .in(jsonBody[SessionModel.ManualReview.ManualReviewRequest])
    .out(jsonBody[SessionModel.ManualReview.ManualReviewResponse])
    .errorOut(oneOf(
      statusMapping(StatusCode.BadRequest, jsonBody[ErrorsModel.FailureResponse400]),
      statusMapping(StatusCode.Unauthorized, jsonBody[ErrorsModel.FailureResponse401]),
      statusMapping(StatusCode.NotFound, jsonBody[ErrorsModel.FailureResponse404]),
      statusMapping(StatusCode.UnprocessableEntity, jsonBody[ErrorsModel.FailureResponse422]),
      statusMapping(StatusCode.FailedDependency, jsonBody[ErrorsModel.FailureResponse424]),
      statusMapping(StatusCode.InternalServerError, jsonBody[ErrorsModel.FailureResponse500]),
    ))

Upvotes: 3

Views: 1267

Answers (3)

Mike
Mike

Reputation: 861

Changing val to def or lazy val worked for me at first as per the other answers but there were some cases I end up with the same error regardless. I ended up creating a separate object with all the classes and subclasses. ex: `

import sttp.tapir.Schema

object SessionModelSchemas {
  implicit lazy val sSubClass1: Schema[SubClass1] = Schema.derived
  implicit lazy val sSubClass1: Schema[SubClass2] = Schema.derived
  implicit lazy val sSubClass1: Schema[SubClassN] = Schema.derived

  implicit lazy val sSessionModel.ManualReview.ManualReviewResponse: Schema[SessionModel.ManualReview.ManualReviewResponse] = Schema.derived
}

Then where you define the endpoint remove this import (or similar)

import sttp.tapir.generic.auto._

And import your new object instead.

import SessionModelSchemas._

It was really tedious but simple to do. If you miss a class you'll get an error like:

magnolia: could not find Schema.Typeclass for type Option[SubClassN]

Just add it and try again. It's a bit of a maintenance pain but I wasn't able to find another way.

For more info: https://tapir.softwaremill.com/en/latest/endpoint/schemas.html

Upvotes: 1

Ronak Katta
Ronak Katta

Reputation: 11

It could be due to large length of endpoint, for me it worked by changing endpoint from 'val' to 'def' Which would look like def manualReviewEndpoint

Upvotes: 1

Kay
Kay

Reputation: 19660

It looks like because i had so many endpoints with many statusMappings that it was causing the constructor to become too large.

I fixed this issue by putting manualReviewEndpoint into its own object.

Upvotes: 2

Related Questions