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

Help needed with json response erroring when 200 code response #35

Closed
justindunn opened this issue Apr 21, 2017 · 6 comments
Closed

Help needed with json response erroring when 200 code response #35

justindunn opened this issue Apr 21, 2017 · 6 comments
Assignees
Milestone

Comments

@justindunn
Copy link

I saw a related issue to this problem i'm having already in the closed issues, but the fixes there didn't do the trick for me. I'm getting a json response and without error from my server (200 code) but i'm getting an error from xcode/swift. Below is said error:

{ status code: 200, headers { "Cache-Control" = "max-age=0, private, must-revalidate"; Connection = close; "Content-Type" = "application/json; charset=utf-8"; Etag = "W/\"f49d10c019a7a3b8c095a8da43570f5f\""; Server = thin; "X-Content-Type-Options" = nosniff; "X-Frame-Options" = SAMEORIGIN; "X-Meta-Request-Version" = "0.3.4"; "X-Request-Id" = "129f985f-31a5-4fe7-a09b-3e8d0cb4823a"; "X-Runtime" = "0.433514"; "X-XSS-Protection" = "1; mode=block"; } }), data: Optional(653 bytes), error: Optional(Alamofire.AFError.responseValidationFailed(Alamofire.AFError.ResponseValidationFailureReason.unacceptableContentType(acceptableContentTypes: ["application/vnd.api+json"], responseContentType: "application/json"))), errorModel: Optional(wecounsel.DataController.FetchFailed))

Here is what the json looks like:

{ "meta" : { "current_user_abilities" : { "facilitator" : false, "provider" : true, "consumer" : false, "org_admin" : false, "admin" : false } }, "data" : [ { "id" : "session-4763-20170422123000", "links" : { "self" : "http:\/\/localhost:3000\/v1\/sessions\/4763\/repeated\/starts\/2017-04-22%2012:30:00%20-0400\/ends\/2017-04-22%2013:30:00%20-0400" }, "type" : "session", "attributes" : { "end" : "2017-04-22 13:30:00", "start" : "2017-04-22 12:30:00", "title" : "Session", "current_user_participates" : true, "description" : "<p>Session with Doc Brown and Austin Consumer for Follow up.<\/p><p>12:30 PM - 01:30 PM EDT<\/p>", "repeat_instance" : true, "session_mode" : "video_session" } } ] }

Here is my functions I'm using:

`
public class DataController {
static let tron = TRON(baseURL: GlobalVariables().baseURL)

class Fetched: JSONDecodable {
    let response: JSON
    required init(json: JSON) throws {
        let response = json
        self.response = response
    }
}

class FetchFailed: JSONDecodable {
    let response: JSON
    required init(json: JSON) throws {
        print(json)
        let response = json
        self.response = response
}

func Get(parameters: [String:Any], path: String) -> APIRequest<Fetched, FetchFailed> {
    let request: APIRequest<Fetched, FetchFailed> = DataController.tron.request(path)
    request.parameters = parameters
    request.headers = ["Accept":"application/vnd.api+json"]

// DataController.tron.headerBuilder = HeaderBuilder(defaultHeaders: [:])
return request
}`

func getData(parameters: [String:Any], finished: @escaping () -> Void) { DataController().Get(parameters: parameters, path: "/v1/calendar").perform(withSuccess: { (Fetched) in if let eventsArray = Fetched.response["data"].array { self.events += eventsArray } print(self.events, "here are the events") finished() }) { (FetchFailed) in print(FetchFailed) finished() } }

anyone have any idea of whats going on? i know the json has an array but i don't think thats the issue is it?

@justindunn
Copy link
Author

So I'm still trying to figure out this bug I've created, and it seems like the response json is sending back a content type of "application/json", the api i'm working with only allows me to have the one header of request.headers = ["Accept":"application/vnd.api+json"] if i add request.headers = ["Accept":"application/json"] it will not authenticate the api call. Is there a way I can let tron know that the response is going to need to be application/json with out adding it to the header?

@DenTelezhkin
Copy link
Member

Hey!

It seems like you set "application/vnd.api+json" value in "Accept" header, but your server responds to you with "application/json" instead, which is why validation fails.

Can you elaborate more on what do you mean by "API will not authenticate API call"?

@justindunn
Copy link
Author

when i use "application/json" instead as the "Accept" value in swift, my rails server response is like this
Started GET "/v1/calendar?access_token=[FILTERED]&ends_at=Apr%2022%2C%202017%2C%2011%3A59%3A59%20PM%20EDT&event_type=sessions&starts_at=Apr%2021%2C%202017%2C%2012%3A00%3A00%20AM%20EDT" for 127.0.0.1 at 2017-04-21 16:54:03 -0400 Processing by API::V1::CalendarController#index as JSON Parameters: {"access_token"=>"[FILTERED]", "ends_at"=>"Apr 22, 2017, 11:59:59 PM EDT", "event_type"=>"sessions", "starts_at"=>"Apr 21, 2017, 12:00:00 AM EDT"} Doorkeeper::AccessToken Load (0.4ms) SELECT oauth_access_tokens.* FROM oauth_access_tokensWHEREoauth_access_tokens.token= '1c60b04440712e9a7ee4ba161ff35c61b64618635c2d194a539470bf803ed75d' LIMIT 1 Doorkeeper::AccessToken Load (0.3ms) SELECT oauth_access_tokens.* FROM oauth_access_tokensWHEREoauth_access_tokens.refresh_token= '' LIMIT 1 (0.2ms) BEGIN (0.2ms) COMMIT User Load (0.4ms) SELECT users.* FROM usersWHEREusers.deleted_atIS NULL ANDusers.id= 122 LIMIT 1 [active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.12ms) Filter chain halted as :ensure_valid_accept_media_type rendered or redirected Completed 406 Not Acceptable in 29ms (Views: 16.9ms | ActiveRecord: 1.5ms | Solr: 0.0ms)

you can see that ensure_valid_accept_media_type is getting called from here https://github.com/cerebris/jsonapi-resources/blob/master/lib/jsonapi/acts_as_resource_controller.rb#L179 (i believe) and my api developer is telling me that we should only be using "application/vnd.api+json", so for me now its like a catch 22, the server reacts the way its supposed to with ""application/vnd.api+json" and i get back the json, but it fails to validate in swift, but if i switch to just plain ""application/json" for the Accept value it fails in the rails server to authenticate, if i put both, it still fails on rails server for authentication

@DenTelezhkin
Copy link
Member

Ok, so here's my thoughts on this

  1. It's weird that you have to set "Accept" header to "application/vnd.api+json", and your server responds to you with mime-type "application/json", maybe it's something fixable on server side?

  2. Indeed, validation is not customizable in TRON, and we certainly need to add ability to modify acceptable content-types, right now we only allow default behaviour from Alamofire - https://github.com/MLSDev/TRON/blob/master/Source/Core/APIRequest.swift#L109

We will develop feature that will allow changing acceptable content types for 3.1 release. I will leave this issue open for now.

@DenTelezhkin DenTelezhkin added this to the 3.1.0 milestone Apr 23, 2017
@DenTelezhkin DenTelezhkin self-assigned this Apr 23, 2017
@DenTelezhkin
Copy link
Member

I implemented this on master: eb7e053

Now you will be able to customize validations however you like. For example, if you want to validate only status codes and not validate mime types, you can do:

let request: APIRequest<Fetched, FetchFailed> = DataController.tron.request(path)
    request.parameters = parameters
    request.headers = ["Accept":"application/vnd.api+json"]
    request.validationClosure = { $0.validate(statusCode: (200..<300) }

I'm not ready to make a release, but you can try installing from master and see if this helps to solve your problem.

@justindunn
Copy link
Author

YES! That worked! Thank you very much for your help! Really enjoying TRON for my API needs! Now that I have this everything is working with the updated API security our API developer has been working on. You guys do great work and thanks again for taking your time to help me with this issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants