Releases: sangria-graphql/sangria
v0.4.2
-
Query complexity calculation mechanism is implemented (#85). This mechanism makes a rough estimation of the query complexity before it is executed.
Every field in the query gets a default score1.0
. The "complexity" of the query is the sum of all field scores. You can customize the
field score withcomplexity
argument:Field("pets", OptionType(ListType(PetType)), arguments = Argument("limit", IntType) :: Nil, complexity = Some((args, childrenScore) ⇒ 25.0D + args.arg[Int]("limit") * childrenScore), resolve = ctx ⇒ ...)
If you would like to use this feature, you need to provide
measureComplexity
argument to theExecutor
. For example:val rejectComplexQueries = (c: Double) ⇒ if (c > 1000) throw new IllegalArgumentException(s"Too complex query: max allowed complexity is 1000.0, but got $c") else () val exceptionHandler: PartialFunction[(ResultMarshaller, Throwable), HandledException] = { case (m, e: IllegalArgumentException) ⇒ HandledException(e.getMessage) } Executor.execute(schema, query, exceptionHandler = exceptionHandler, measureComplexity = Some(rejectComplexQueries))
The complexity of full introspection query (used by tools like GraphiQL) is
102.0
.
You can find more information in the docs: Protection Against Malicious Queries -
json4s-jackson is now supported in addition to native (#84). This results in minor import change:
// before sangria.integration.json4s._ // after // either (same behaviour as before) sangria.integration.json4s.native._ //or sangria.integration.json4s.jackson._
-
json4s is updated to version 3.3.0 (#84)
-
Provide a helpful error messages if schema has a broken circular references (which cause
fields
to be null) (#83)
v0.4.1
For the most part implemented spec changes. Now compatible with "October 2015" version of the GraphQL spec.
-
Type condition optional on inline fragments. (#82) (spec change)
-
Make operation name optional (#81) (spec change)
-
Introspection descriptions for scalars and introspection (#80)
-
beforeField
now able to replace value and preventresolve
call (#79). This can be useful for things like caching. It contains minor breaking change - return type ofbeforeField
has changed. If you are implementing it, just returncontinue
if yourFieldVal
wasUnit
orcontinue(someFieldVal)
. -
Projection
andNoProjection
should be tags instead of resolve function wrappers (#78). Backwards-incompatible change: you need to replace
Projection
withProjectionName
tag andNoProjection
withProjectionExclude
tag. here is an example:// before Field("id", StringType, Some("The id of the droid."), resolve = Projection("_id", _.value.id)), // after Field("id", StringType, Some("The id of the droid."), tags = ProjectionName("_id") :: Nil, resolve = _.value.id)
v0.4.0
This release contains quite a few backwards-incompatible changes, but fear not - all of them are renames and similar minor changes which should be easy to migrate.
I collected all of them in the change list below. They were necessary in order to ensure consistent naming and improve the structure and flexibility of the library.
-
#68 - Better handling of default input values. It's a part of ongoing effort to improve handling of input objects (#37). Default values should now have an instance
ofToInput
type-class which is defined for all supported input types like scala map-like data structures, different json ASTs, etc.
It even supports things likeWrites
from play-json orJsonFormat
from spray-json by default. This means that you can use your domain objects (likeUser
orApple
) as a default value for input fields or arguments
as long as you haveWrites
orJsonFormat
defined for them. The mechanism is very extensible, of course: you just need to define implicitToInput[T]
for a class you want to use as a default value.
This change makes it impossible to verify the default value type at compile time, since it can have any shape, like Json AST or maybe even some binary format. Don't worry though,
at a schema creation time all default values would be validated according to the input type. You can find more info in docs and auth example -
#77 - Middleware support. This addition has a huge potential: you can measure performance, collect metrics, enforce security, etc. on a field and query level. Moreover
it makes it much easier for people to share standard middleware in a libraries (e.g. sangria-security, sangria-graphite, sangria-influxdb, etc.). In order to ensure generic classification of
fields, every field now got a generic list orFieldTag
s which allow to provide user-defined meta information about this field
(just to highlight a few examples:Permission("ViewOrders")
,Authorized
,Measured
, etc.). -
#76 - You can now provide
maxQueryDepth
toExecutor
. It will then enforce this constraint for all queries (very useful if query has recursive types) Docs -
#69 -
DeferredResolver
now gotuserContext
as an argument. (breaking change: you need to provide a type parameter and one extra argument inresolve
for yourDeferredResolver
s. you you are not interested inuserContext
, you can just useAny
type) -
Renamed Json support objects in order to make more concise import syntax (breaking change: you need to rename imports as well):
sangria.integration.CirceSupport
->sangria.integration.circe
sangria.integration.Json4sSupport
->sangria.integration.json4s
sangria.integration.PlayJsonSupport
->sangria.integration.playJson
sangria.integration.SprayJsonSupport
->sangria.integration.sprayJson
-
ResultMarshaller
andInputUnmarshaller
are moved in theintegration
package -
Renamed execution
arguments
tovariables
in order to be consistent with the spec (breaking change: you need to rename this argument as well, if you are using named arguments) -
Refactored variables and
InputUnmarshaller
. In order to avoid extra complexity it now does not have a dependent type. Instead it uses "type tagging" for scala map variables.
It's a minor breaking change. If you are providing execution variables as a scala map, then you need to usemapVars
oremptyMapVars
which are defined inInputUnmarshaller
companion object (these functions do not wrapMap
- they only needed to ensure type constraints):Executor.execute(mySchema, query, variables = mapVars(Map("someId" -> "1000"))) // or Executor.execute(mySchema, query, variables = mapVars("someId" -> "1000"))
-
#72 -
scala.util.Try
now can be returned fromresolve
in order to indicate a successful or failed result -
#65 -
DeprecationTracker
should be called even if deprecation is in the interface type -
#66 -
DeprecationTracker
should provide more contextual information (breaking change: the signature ofdeprecatedFieldUsed
is changed. It now provides much more contextual information, but you need to update the code that implements it) -
#74 - Improved unicode handling (spec change)
-
#67 - circe integration throws NoSuchElementException during execution
-
#75 - Identical documents should be equal
-
#73 - Verify input field uniqueness (spec change - new validation rule)
-
Minor bugfixes
v0.3.1
- #58 - Implement CirceJsonSupport in order to be able to integrate with Circe
- #53 - Add
map
inAction
- #53 - Ensure Ctx proper inheritance behavior
- #33 -
grapql
string context macro to create parsed document and verify query at compile time (big thanks to @dlreeves for implementing this feature). Here is an example how you can use it:
import sangria.macros._
val queryAst = graphql"""
query FetchSomeIDQuery {
human(id: "1000") {
name
}
}
"""
If there is a syntax error in the query, you will see it at the compile time.
v0.3.0
-
#45 - Added
Long
scalar type -
#49 -
UpdateCtxAction
should also work for query types -
#50 - Sanity check - fields should have unique name within the same type definition
-
#31, #32 - More test coverage for "projections" and "deferred" features
-
#51 - Custom exception handler now should return
message
and list of additional filed -
The
interfaces
property syntax changed. In order to ensure type safety, improve type inference and allow type-class based relations betweenInterfaceType
andObjectType
you now need to use following syntax:val PersonType = ObjectType("Person", interfaces = interfaces[Unit, Person](NamedType, BeingType), fields = ...)
instead of old syntax
val PersonType = ObjectType[Unit, Person]("Person", interfaces = NamedType :: BeingType :: Nil, fields = ...) // or val PersonType = ObjectType[Unit, Person]("Person", interfaces = List(NamedType, BeingType), fields = ...)
-
Fields in
ObjectType
andInterfaceType
got small convenience method fields. You now can use it like this:val DogType = ObjectType("Dog", fields[Unit, Dog]( Field("name", OptionType(StringType), resolve = _.value.name), Field("barks", OptionType(BooleanType), resolve = _.value.barks)))
-
withPossibleTypes
was introduced onInterfaceType
andField
in order to provide a convenient way to the list of possible implementation types of interface -
Added convenience method
Executor.execute
-
Other minor improvements to make sangria-relay possible
v0.2.2
v0.2.1
- Spec changes - sew validation rules:
LoneAnonymousOperation
UniqueArgumentNames
UniqueFragmentNames
UniqueOperationNames
v0.2.0
- groupId is changed to org.sangria-graphql
- Added missing query validation rules (#30 #29 #28 #27 #26 #25 #24 #23)
- #36 - Change semantics of
Projector
featureProjector
now gets all of the fields, not only fields marked withProjection
Projection
now allows to customize the nameNoProjection
allows to remove field from projections listProjectior
allows to specify how deep it should look (the level arg)
v0.1.0
Initial feature-complete release