Documentation

You are viewing the documentation for the 2.3.x release series. The latest stable release series is 2.4.x.

§HTTP ile JSON

Play, HTTP API’nin JSON kütüphanesi ile birlikte kullanılması ile içerik türü JSON olan HTTP istek ve yanıtlarını destekler.

Controller’lar, Action’lar ve yönlendirme hakkında ayrıntılı bilgi için HTTP Programlama sayfasına bakınız.

Gerekli kavramları, varlıkları GET ile almak ve POST ile yaratmak için bir RESTful web servis geliştirerek göstereceğiz. Bu servis tüm veri için içerik türü olarak JSON kullanacak.

Servisimiz için kullanacağımız model aşağıda yer alıyor:

case class Location(lat: Double, long: Double)

case class Place(name: String, location: Location)

object Place {
    
  var list: List[Place] = {
    List(
      Place(
        "Sandleford",
        Location(51.377797, -1.318965)
      ),
      Place(
        "Watership Down",
        Location(51.235685, -1.309197)
      )
    )
  }
    
  def save(place: Place) = {
    list = list ::: List(place)
  }
}

§Bir varlık listesini JSON biçiminde sunmak

Controller’ımıza gerekli import’ları ekleyerek başlayalım.

import play.api.mvc._
import play.api.libs.json._
import play.api.libs.functional.syntax._

object Application extends Controller {
  
}

Action’ı yazmadan evvel modelimizden JsValue görünümüne dönüşüm yapacak bir bağlantıya ihtiyacımız var. Bu bağlantıyı örtük bir Writes[Place] tanımlayarak sağlıyoruz.

implicit val locationWrites: Writes[Location] = (
  (JsPath \ "lat").write[Double] and
  (JsPath \ "long").write[Double]
)(unlift(Location.unapply))

implicit val placeWrites: Writes[Place] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "location").write[Location]
)(unlift(Place.unapply))

Sonra Action’ı yazıyoruz:

def listPlaces = Action {
  val json = Json.toJson(Place.list)
  Ok(json)
}

Action önce bir Place listesi elde ediyor, daha sonra bunları örtük Writes[Place] aracılığıyla Json.toJson kullanarak bir JsValue’ya dönüştürüyor ve bu değeri yanıt gövdesi olarak döndürüyor. Play, yanıtı JSON olarak tanıyacak ve yanıt için gerekli Content-Type başlığı ile gövde değerini setleyecektir.

Geriye yalnızca bu Action için conf/routes dosyasına bir yönlendirme eklemek kalıyor:

GET   /places               controllers.Application.listPlaces

Bu action bir tarayıcı ya da HTTP aracı kullanarak test edilebilir. Bizim örneğimiz UNIX komut satırı aracı cURL kullanıyor.

curl --include http://localhost:9000/places

Yanıt:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 141

[{"name":"Sandleford","location":{"lat":51.377797,"long":-1.318965}},{"name":"Watership Down","location":{"lat":51.235685,"long":-1.309197}}]

§JSON ile yeni bir varlık oluşturmak

Bu Action için bir JsValue’dan bizim modelimize dönüşüm yapacak örtük bir Reads[Place] tanımlamamız gerekiyor.

implicit val locationReads: Reads[Location] = (
  (JsPath \ "lat").read[Double] and
  (JsPath \ "long").read[Double]
)(Location.apply _)

implicit val placeReads: Reads[Place] = (
  (JsPath \ "name").read[String] and
  (JsPath \ "location").read[Location]
)(Place.apply _)

Daha sonra Action’ı tanımlıyoruz.

def savePlace = Action(BodyParsers.parse.json) { request =>
  val placeResult = request.body.validate[Place]
  placeResult.fold(
    errors => {
      BadRequest(Json.obj("status" ->"KO", "message" -> JsError.toFlatJson(errors)))
    },
    place => { 
      Place.save(place)
      Ok(Json.obj("status" ->"OK", "message" -> ("Place '"+place.name+"' saved.") ))  
    }
  )
}

Bu Action bir öncekinden daha karmaşık. Dikkate alınması gereken bazı noktalar şöyle:

Son olarak conf/routes dosyasına bir yönlendirme ekliyoruz:

POST  /places               controllers.Application.savePlace

Bu action’ı geçerli ve geçersiz isteklerle test ederek başarı ve hata durumlarımızı doğrulayacağız.

Geçerli veri ile test:

curl --include
  --request POST
  --header "Content-type: application/json"
  --data '{"name":"Nuthanger Farm","location":{"lat" : 51.244031,"long" : -1.263224}}'
  http://localhost:9000/places

Yanıt:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 57

{"status":"OK","message":"Place 'Nuthanger Farm' saved."}

“name” alanı olmayan geçersiz veri ile test:

curl --include
  --request POST
  --header "Content-type: application/json"
  --data '{"location":{"lat" : 51.244031,"long" : -1.263224}}'
  http://localhost:9000/places

Yanıt:

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 79

{"status":"KO","message":{"obj.name":[{"msg":"error.path.missing","args":[]}]}}

“lat” için hatalı veri türüne sahip geçersiz veri ile test:

curl --include
  --request POST
  --header "Content-type: application/json"
  --data '{"name":"Nuthanger Farm","location":{"lat" : "xxx","long" : -1.263224}}'
  http://localhost:9000/places

Yanıt:

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 92

{"status":"KO","message":{"obj.location.lat":[{"msg":"error.expected.jsnumber","args":[]}]}}

§Özet

Play, JSON ile REST geliştirmeyi desteklemek üzere tasarlanmıştır. Dolayısıyla bu servisleri geliştirmenin basit olduğunu umuyoruz. İşin çoğu bir sonraki bölümde ayrıntılı olarak açıklanan modeliniz için Reads ve Writes yazmaktan ibaret.

Sonraki: JSON Reads/Writes/Formats Combinator'lar


Dokümantasyonun bu çevirisi Play ekibi tarafından yapılmamaktadır. Eğer bir hata bulduysanız, bu sayfanın kaynak kodu burada bulunmaktadır. Dokümantasyon yönergelerini okuduktan sonra lütfen katkı yapmaktan çekinmeyin.